summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2018-12-20 22:05:36 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2019-01-23 18:10:06 -0500
commit4c2c2c40fde17c85013e00a6f3303a99e2b32c12 (patch)
tree324a2c22eb61cb913e3e162e163f7baff14152cf /lib/sqlalchemy/sql
parent5832f7172907a8151345d95061f93784ce4bb9b1 (diff)
downloadsqlalchemy-4c2c2c40fde17c85013e00a6f3303a99e2b32c12.tar.gz
Add deprecation warnings to all deprecated APIs
A large change throughout the library has ensured that all objects, parameters, and behaviors which have been noted as deprecated or legacy now emit ``DeprecationWarning`` warnings when invoked. As the Python 3 interpreter now defaults to displaying deprecation warnings, as well as that modern test suites based on tools like tox and pytest tend to display deprecation warnings, this change should make it easier to note what API features are obsolete. See the notes added to the changelog and migration notes for further details. Fixes: #4393 Change-Id: If0ea11a1fc24f9a8029352eeadfc49a7a54c0a1b
Diffstat (limited to 'lib/sqlalchemy/sql')
-rw-r--r--lib/sqlalchemy/sql/compiler.py58
-rw-r--r--lib/sqlalchemy/sql/ddl.py16
-rw-r--r--lib/sqlalchemy/sql/elements.py94
-rw-r--r--lib/sqlalchemy/sql/schema.py78
-rw-r--r--lib/sqlalchemy/sql/selectable.py60
-rw-r--r--lib/sqlalchemy/sql/sqltypes.py131
6 files changed, 252 insertions, 185 deletions
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index a3184f270..b703c59f2 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -315,7 +315,7 @@ class Compiled(object):
"The :meth:`.Compiled.compile` method is deprecated and will be "
"removed in a future release. The :class:`.Compiled` object "
"now runs its compilation within the constructor, and this method "
- "does nothing."
+ "does nothing.",
)
def compile(self):
"""Produce the internal string representation of this element.
@@ -3442,6 +3442,7 @@ class IdentifierPreparer(object):
def quote_schema(self, schema, force=None):
"""Conditionally quote a schema name.
+
The name is quoted if it is a reserved word, contains quote-necessary
characters, or is an instance of :class:`.quoted_name` which includes
``quote`` set to ``True``.
@@ -3450,17 +3451,30 @@ class IdentifierPreparer(object):
quoting behavior for schema names.
:param schema: string schema name
- :param force: this parameter is no longer used.
+ :param force: unused
- .. deprecated:: 0.9
+ .. deprecated:: 0.9
- The :paramref:`.IdentifierPreparer.force` parameter is deprecated
- and will be removed in a future release. Quoting preference
- is now intrinsic to the string being quoted by making use of the
- :class:`.quoted_name` class.
+ The :paramref:`.IdentifierPreparer.quote_schema.force`
+ parameter is deprecated and will be removed in a future
+ release. This flag has no effect on the behavior of the
+ :meth:`.IdentifierPreparer.quote` method; please refer to
+ :class:`.quoted_name`.
"""
- return self.quote(schema, force)
+ if force is not None:
+ # not using the util.deprecated_params() decorator in this
+ # case because of the additional function call overhead on this
+ # very performance-critical spot.
+ util.warn_deprecated(
+ "The IdentifierPreparer.quote_schema.force parameter is "
+ "deprecated and will be removed in a future release. This "
+ "flag has no effect on the behavior of the "
+ "IdentifierPreparer.quote method; please refer to "
+ "quoted_name()."
+ )
+
+ return self.quote(schema)
def quote(self, ident, force=None):
"""Conditionally quote an identfier.
@@ -3473,16 +3487,28 @@ class IdentifierPreparer(object):
quoting behavior for identifier names.
:param ident: string identifier
- :param force: this parameter is no longer used.
+ :param force: unused
- .. deprecated:: 0.9
+ .. deprecated:: 0.9
- The :paramref:`.IdentifierPreparer.force` parameter is deprecated
- and will be removed in a future release. Quoting preference
- is now intrinsic to the string being quoted by making use of the
- :class:`.quoted_name` class.
+ The :paramref:`.IdentifierPreparer.quote.force`
+ parameter is deprecated and will be removed in a future
+ release. This flag has no effect on the behavior of the
+ :meth:`.IdentifierPreparer.quote` method; please refer to
+ :class:`.quoted_name`.
"""
+ if force is not None:
+ # not using the util.deprecated_params() decorator in this
+ # case because of the additional function call overhead on this
+ # very performance-critical spot.
+ util.warn_deprecated(
+ "The IdentifierPreparer.quote.force parameter is "
+ "deprecated and will be removed in a future release. This "
+ "flag has no effect on the behavior of the "
+ "IdentifierPreparer.quote method; please refer to "
+ "quoted_name()."
+ )
force = getattr(ident, "quote", None)
@@ -3580,10 +3606,10 @@ class IdentifierPreparer(object):
result = self.quote_schema(effective_schema) + "." + result
return result
- def format_schema(self, name, quote=None):
+ def format_schema(self, name):
"""Prepare a quoted schema name."""
- return self.quote(name, quote)
+ return self.quote(name)
def format_column(
self,
diff --git a/lib/sqlalchemy/sql/ddl.py b/lib/sqlalchemy/sql/ddl.py
index 3deb588ab..954f769ef 100644
--- a/lib/sqlalchemy/sql/ddl.py
+++ b/lib/sqlalchemy/sql/ddl.py
@@ -106,7 +106,7 @@ class DDLElement(Executable, _DDLCompiles):
"The :meth:`.DDLElement.execute_at` method is deprecated and will "
"be removed in a future release. Please use the :class:`.DDLEvents` "
"listener interface in conjunction with the "
- ":meth:`.DDLElement.execute_if` method."
+ ":meth:`.DDLElement.execute_if` method.",
)
def execute_at(self, event_name, target):
"""Link execution of this DDL to the DDL lifecycle of a SchemaItem.
@@ -317,6 +317,14 @@ class DDL(DDLElement):
__visit_name__ = "ddl"
+ @util.deprecated_params(
+ on=(
+ "0.7",
+ "The :paramref:`.DDL.on` parameter is deprecated and will be "
+ "removed in a future release. Please refer to "
+ ":meth:`.DDLElement.execute_if`.",
+ )
+ )
def __init__(self, statement, on=None, context=None, bind=None):
"""Create a DDL statement.
@@ -331,12 +339,6 @@ class DDL(DDLElement):
:param on:
- .. deprecated:: 0.7
-
- The :paramref:`.DDL.on` parameter is deprecated and will be
- removed in a future release. Please refer to
- :meth:`.DDLElement.execute_if`.
-
Optional filtering criteria. May be a string, tuple or a callable
predicate. If a string, it will be compared to the name of the
executing database dialect::
diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py
index fae25cc2c..71f346f45 100644
--- a/lib/sqlalchemy/sql/elements.py
+++ b/lib/sqlalchemy/sql/elements.py
@@ -461,21 +461,27 @@ class ClauseElement(Visitable):
"ascii", "backslashreplace"
) # noqa
+ @util.deprecated(
+ "0.9",
+ "The :meth:`.ClauseElement.__and__` method is deprecated and will "
+ "be removed in a future release. Conjunctions should only be "
+ "used from a :class:`.ColumnElement` subclass, e.g. "
+ ":meth:`.ColumnElement.__and__`.",
+ )
def __and__(self, other):
"""'and' at the ClauseElement level.
-
- .. deprecated:: 0.9.5 - conjunctions are intended to be
- at the :class:`.ColumnElement`. level
-
"""
return and_(self, other)
+ @util.deprecated(
+ "0.9",
+ "The :meth:`.ClauseElement.__or__` method is deprecated and will "
+ "be removed in a future release. Conjunctions should only be "
+ "used from a :class:`.ColumnElement` subclass, e.g. "
+ ":meth:`.ColumnElement.__or__`.",
+ )
def __or__(self, other):
"""'or' at the ClauseElement level.
-
- .. deprecated:: 0.9.5 - conjunctions are intended to be
- at the :class:`.ColumnElement`. level
-
"""
return or_(self, other)
@@ -1280,6 +1286,10 @@ class TextClause(Executable, ClauseElement):
)
_is_implicitly_boolean = False
+ def __and__(self, other):
+ # support use in select.where(), query.filter()
+ return and_(self, other)
+
@property
def _select_iterable(self):
return (self,)
@@ -1311,6 +1321,28 @@ class TextClause(Executable, ClauseElement):
self.text = self._bind_params_regex.sub(repl, text)
@classmethod
+ @util.deprecated_params(
+ autocommit=(
+ "0.6",
+ "The :paramref:`.text.autocommit` parameter is deprecated and "
+ "will be removed in a future release. Please use the "
+ ":paramref:`.Connection.execution_options.autocommit` parameter "
+ "in conjunction with the :meth:`.Executable.execution_options` "
+ "method.",
+ ),
+ bindparams=(
+ "0.9",
+ "The :paramref:`.text.bindparams` parameter "
+ "is deprecated and will be removed in a future release. Please "
+ "refer to the :meth:`.TextClause.bindparams` method.",
+ ),
+ typemap=(
+ "0.9",
+ "The :paramref:`.text.typemap` parameter is "
+ "deprecated and will be removed in a future release. Please "
+ "refer to the :meth:`.TextClause.columns` method.",
+ ),
+ )
def _create_text(
self, text, bind=None, bindparams=None, typemap=None, autocommit=None
):
@@ -1389,15 +1421,8 @@ class TextClause(Executable, ClauseElement):
to specify bind parameters; they will be compiled to their
engine-specific format.
- :param autocommit:
-
- .. deprecated:: 0.6
-
- The :paramref:`.text.autocommit` flag is deprecated and
- will be removed in a future release. Please use the
- :paramref:`.Connection.execution_options.autocommit` parameter
- in conjunction with the :meth:`.Executable.execution_options`
- method.
+ :param autocommit: whether or not to set the "autocommit" execution
+ option for this :class:`.TextClause` object.
:param bind:
an optional connection or engine to be used for this text query.
@@ -1405,27 +1430,22 @@ class TextClause(Executable, ClauseElement):
:param bindparams:
A list of :func:`.bindparam` instances used to
provide information about parameters embedded in the statement.
+
E.g.::
stmt = text("SELECT * FROM table WHERE id=:id",
bindparams=[bindparam('id', value=5, type_=Integer)])
- .. deprecated:: 0.9 the :paramref:`.TextClause.bindparams` parameter
- is deprecated and will be removed in a future release. Please
- refer to the :meth:`.TextClause.bindparams` method.
-
:param typemap:
A dictionary mapping the names of columns represented in the columns
- clause of a ``SELECT`` statement to type objects, e.g.::
+ clause of a ``SELECT`` statement to type objects.
+
+ E.g.::
stmt = text("SELECT * FROM table",
typemap={'id': Integer, 'name': String},
)
- .. deprecated:: 0.9 The :paramref:`.TextClause.typemap` argument is
- deprecated and will be removed in a future release. Please
- refer to the :meth:`.TextClause.columns` method.
-
.. seealso::
:ref:`sqlexpression_text` - in the Core tutorial
@@ -1439,10 +1459,6 @@ class TextClause(Executable, ClauseElement):
if typemap:
stmt = stmt.columns(**typemap)
if autocommit is not None:
- util.warn_deprecated(
- "autocommit on text() is deprecated. "
- "Use .execution_options(autocommit=True)"
- )
stmt = stmt.execution_options(autocommit=autocommit)
return stmt
@@ -1511,12 +1527,6 @@ class TextClause(Executable, ClauseElement):
timestamp=datetime.datetime(2012, 10, 8, 15, 12, 5)
)
-
- .. versionadded:: 0.9.0 The :meth:`.TextClause.bindparams` method
- supersedes the argument ``bindparams`` passed to
- :func:`~.expression.text`.
-
-
"""
self._bindparams = new_params = self._bindparams.copy()
@@ -1631,8 +1641,7 @@ class TextClause(Executable, ClauseElement):
.. versionadded:: 0.9.0 :func:`.text` can now be converted into a
fully featured "selectable" construct using the
- :meth:`.TextClause.columns` method. This method supersedes the
- ``typemap`` argument to :func:`.text`.
+ :meth:`.TextClause.columns` method.
"""
@@ -3364,13 +3373,16 @@ class Over(ColumnElement):
return lower, upper
@property
+ @util.deprecated(
+ "1.1",
+ "the :attr:`.Over.func` member of the :class:`.Over` "
+ "class is deprecated and will be removed in a future release. "
+ "Please refer to the :attr:`.Over.element` attribute.",
+ )
def func(self):
"""the element referred to by this :class:`.Over`
clause.
- .. deprecated:: 1.1 the :attr:`.Over.func` member of the :class:`.Over`
- class is deprecated and will be removed in a future release. Please
- refer to the :attr:`.Over.element` attribute.
"""
return self.element
diff --git a/lib/sqlalchemy/sql/schema.py b/lib/sqlalchemy/sql/schema.py
index 43a2e5d0f..d9555b196 100644
--- a/lib/sqlalchemy/sql/schema.py
+++ b/lib/sqlalchemy/sql/schema.py
@@ -118,7 +118,8 @@ class SchemaItem(SchemaEventTarget, visitors.Visitable):
"The :attr:`.SchemaItem.quote` attribute is deprecated and will be "
"removed in a future release. Use the :attr:`.quoted_name.quote` "
"attribute on the ``name`` field of the target schema item to retrieve"
- "quoted status.")
+ "quoted status.",
+ )
def quote(self):
"""Return the value of the ``quote`` flag passed
to this schema object, for those schema items which
@@ -394,7 +395,7 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
name, specify the flag ``quote_schema=True`` to the constructor, or use
the :class:`.quoted_name` construct to specify the name.
- :param useexisting: Deprecated. Use :paramref:`.Table.extend_existing`.
+ :param useexisting: the same as :paramref:`.Table.extend_existing`.
:param comment: Optional string that will render an SQL comment on table
creation.
@@ -411,6 +412,14 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
__visit_name__ = "table"
+ @util.deprecated_params(
+ useexisting=(
+ "0.7",
+ "The :paramref:`.Table.useexisting` parameter is deprecated and "
+ "will be removed in a future release. Please use "
+ ":paramref:`.Table.extend_existing`.",
+ )
+ )
def __new__(cls, *args, **kw):
if not args:
# python3k pickle seems to call this
@@ -429,8 +438,6 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
keep_existing = kw.pop("keep_existing", False)
extend_existing = kw.pop("extend_existing", False)
if "useexisting" in kw:
- msg = "useexisting is deprecated. Use extend_existing."
- util.warn_deprecated(msg)
if extend_existing:
msg = "useexisting is synonymous with extend_existing."
raise exc.ArgumentError(msg)
@@ -475,7 +482,8 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
"The :meth:`.SchemaItem.quote` method is deprecated and will be "
"removed in a future release. Use the :attr:`.quoted_name.quote` "
"attribute on the ``schema`` field of the target schema item to "
- "retrieve quoted status.")
+ "retrieve quoted status.",
+ )
def quote_schema(self):
"""Return the value of the ``quote_schema`` flag passed
to this :class:`.Table`.
@@ -763,12 +771,15 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
constraint._set_parent_with_dispatch(self)
+ @util.deprecated(
+ "0.7",
+ "the :meth:`.Table.append_ddl_listener` method is deprecated and "
+ "will be removed in a future release. Please refer to "
+ ":class:`.DDLEvents`.",
+ )
def append_ddl_listener(self, event_name, listener):
"""Append a DDL event listener to this ``Table``.
- .. deprecated:: 0.7
- See :class:`.DDLEvents`.
-
"""
def adapt_listener(target, connection, **kw):
@@ -2579,22 +2590,15 @@ class DefaultClause(FetchedValue):
return "DefaultClause(%r, for_update=%r)" % (self.arg, self.for_update)
+@util.deprecated_cls(
+ "0.6",
+ ":class:`.PassiveDefault` is deprecated and will be removed in a "
+ "future release. Please refer to :class:`.DefaultClause`.",
+)
class PassiveDefault(DefaultClause):
"""A DDL-specified DEFAULT column value.
-
- .. deprecated:: 0.6
-
- The :class:`.PassiveDefault` class is deprecated and will be removed
- in a future release. Please use :class:`.DefaultClause`.
-
"""
- @util.deprecated(
- "0.6",
- ":class:`.PassiveDefault` is deprecated and will be removed in a "
- "future release. Use :class:`.DefaultClause`.",
- False,
- )
def __init__(self, *arg, **kw):
DefaultClause.__init__(self, *arg, **kw)
@@ -3711,13 +3715,21 @@ class MetaData(SchemaItem):
__visit_name__ = "metadata"
+ @util.deprecated_params(
+ reflect=(
+ "0.8",
+ "The :paramref:`.MetaData.reflect` flag is deprecated and will "
+ "be removed in a future release. Please use the "
+ ":meth:`.MetaData.reflect` method.",
+ )
+ )
def __init__(
self,
bind=None,
reflect=False,
schema=None,
quote_schema=None,
- naming_convention=DEFAULT_NAMING_CONVENTION,
+ naming_convention=None,
info=None,
):
"""Create a new MetaData object.
@@ -3731,12 +3743,6 @@ class MetaData(SchemaItem):
Optional, automatically load all tables from the bound database.
Defaults to False. ``bind`` is required when this option is set.
- .. deprecated:: 0.8
-
- The :paramref:`.MetaData.reflect` flag is deprecated and will
- be removed in a future release. Please use the
- :meth:`.MetaData.reflect` method.
-
:param schema:
The default schema to use for the :class:`.Table`,
:class:`.Sequence`, and potentially other objects associated with
@@ -3877,7 +3883,11 @@ class MetaData(SchemaItem):
"""
self.tables = util.immutabledict()
self.schema = quoted_name(schema, quote_schema)
- self.naming_convention = naming_convention
+ self.naming_convention = (
+ naming_convention
+ if naming_convention
+ else DEFAULT_NAMING_CONVENTION
+ )
if info:
self.info = info
self._schemas = set()
@@ -3886,10 +3896,6 @@ class MetaData(SchemaItem):
self.bind = bind
if reflect:
- util.warn_deprecated(
- "reflect=True is deprecate; please "
- "use the reflect() method."
- )
if not bind:
raise exc.ArgumentError(
"A bind must be supplied in conjunction "
@@ -4180,11 +4186,15 @@ class MetaData(SchemaItem):
except exc.UnreflectableTableError as uerr:
util.warn("Skipping table %s: %s" % (name, uerr))
+ @util.deprecated(
+ "0.7",
+ "the :meth:`.MetaData.append_ddl_listener` method is deprecated and "
+ "will be removed in a future release. Please refer to "
+ ":class:`.DDLEvents`.",
+ )
def append_ddl_listener(self, event_name, listener):
"""Append a DDL event listener to this ``MetaData``.
- .. deprecated:: 0.7
- See :class:`.DDLEvents`.
"""
diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py
index 0b2155a68..f48fa6f57 100644
--- a/lib/sqlalchemy/sql/selectable.py
+++ b/lib/sqlalchemy/sql/selectable.py
@@ -391,7 +391,7 @@ class FromClause(Selectable):
message="The :meth:`.FromClause.count` method is deprecated, "
"and will be removed in a future release. Please use the "
":class:`.functions.count` function available from the "
- ":attr:`.func` namespace."
+ ":attr:`.func` namespace.",
)
@util.dependencies("sqlalchemy.sql.functions")
def count(self, functions, whereclause=None, **params):
@@ -973,6 +973,15 @@ class Join(FromClause):
return self._join_condition(left, right, a_subset=left_right)
@classmethod
+ @util.deprecated_params(
+ ignore_nonexistent_tables=(
+ "0.9",
+ "The :paramref:`.join_condition.ignore_nonexistent_tables` "
+ "parameter is deprecated and will be removed in a future "
+ "release. Tables outside of the two tables being handled "
+ "are no longer considered.",
+ )
+ )
def _join_condition(
cls,
a,
@@ -995,15 +1004,8 @@ class Join(FromClause):
between the two selectables. If there are multiple ways
to join, or no way to join, an error is raised.
- :param ignore_nonexistent_tables:
-
- .. deprecated:: 0.9
-
- The :paramref:`_join_condition.ignore_nonexistent_tables`
- parameter is deprecated and will be removed in a future
- release. Tables outside of the two tables being handled
- are no longer considered.
-
+ :param ignore_nonexistent_tables: unused - tables outside of the
+ two tables being handled are not considered.
:param a_subset: An optional expression that is a sub-component
of ``a``. An attempt will be made to join to just this sub-component
@@ -2026,7 +2028,7 @@ class SelectBase(HasCTE, Executable, FromClause):
"and will be removed in a future release. Please use the "
"the :paramref:`.Connection.execution_options.autocommit` "
"parameter in conjunction with the "
- ":meth:`.Executable.execution_options` method."
+ ":meth:`.Executable.execution_options` method.",
)
def autocommit(self):
"""return a new selectable with the 'autocommit' flag set to
@@ -2642,6 +2644,24 @@ class Select(HasPrefixes, HasSuffixes, GenerativeSelect):
_memoized_property = SelectBase._memoized_property
_is_select = True
+ @util.deprecated_params(
+ autocommit=(
+ "0.6",
+ "The :paramref:`.select.autocommit` parameter is deprecated "
+ "and will be removed in a future release. Please refer to "
+ "the :paramref:`.Connection.execution_options.autocommit` "
+ "parameter in conjunction with the the "
+ ":meth:`.Executable.execution_options` method in order to "
+ "affect the autocommit behavior for a statement.",
+ ),
+ for_update=(
+ "0.9",
+ "The :paramref:`.select.for_update` parameter is deprecated and "
+ "will be removed in a future release. Please refer to the "
+ ":meth:`.Select.with_for_update` to specify the "
+ "structure of the ``FOR UPDATE`` clause.",
+ ),
+ )
def __init__(
self,
columns=None,
@@ -2712,16 +2732,7 @@ class Select(HasPrefixes, HasSuffixes, GenerativeSelect):
:meth:`.Select.select_from` - full description of explicit
FROM clause specification.
- :param autocommit:
-
- .. deprecated:: 0.6
-
- The :paramref:`.select.autocommit` parameter is deprecated
- and will be removed in a future release. Please refer to
- the :paramref:`.Connection.execution_options.autocommit`
- parameter in conjunction with the the
- :meth:`.Executable.execution_options` method in order to
- affect the autocommit behavior for a statement.
+ :param autocommit: legacy autocommit parameter.
:param bind=None:
an :class:`~.Engine` or :class:`~.Connection` instance
@@ -2762,13 +2773,6 @@ class Select(HasPrefixes, HasSuffixes, GenerativeSelect):
when ``True``, applies ``FOR UPDATE`` to the end of the
resulting statement.
- .. deprecated:: 0.9
-
- The :paramref:`.select.for_update` parameter is deprecated and
- will be removed in a future release. Please refer to the
- :meth:`.Select.with_for_update` to specify the
- structure of the ``FOR UPDATE`` clause.
-
``for_update`` accepts various string values interpreted by
specific backends, including:
diff --git a/lib/sqlalchemy/sql/sqltypes.py b/lib/sqlalchemy/sql/sqltypes.py
index 1d97bf35c..8131be443 100644
--- a/lib/sqlalchemy/sql/sqltypes.py
+++ b/lib/sqlalchemy/sql/sqltypes.py
@@ -137,6 +137,22 @@ class String(Concatenable, TypeEngine):
__visit_name__ = "string"
+ @util.deprecated_params(
+ convert_unicode=(
+ "1.3",
+ "The :paramref:`.String.convert_unicode` parameter is deprecated "
+ "and will be removed in a future release. All modern DBAPIs "
+ "now support Python Unicode directly and this parameter is "
+ "unnecessary.",
+ ),
+ unicode_error=(
+ "1.3",
+ "The :paramref:`.String.unicode_errors` parameter is deprecated "
+ "and will be removed in a future release. This parameter is "
+ "unnecessary for modern Python DBAPIs and degrades performance "
+ "significantly.",
+ ),
+ )
def __init__(
self,
length=None,
@@ -144,6 +160,7 @@ class String(Concatenable, TypeEngine):
convert_unicode=False,
unicode_error=None,
_warn_on_bytestring=False,
+ _expect_unicode=False,
):
"""
Create a string-holding type.
@@ -207,15 +224,9 @@ class String(Concatenable, TypeEngine):
:param unicode_error: Optional, a method to use to handle Unicode
conversion errors. Behaves like the ``errors`` keyword argument to
- the standard library's ``string.decode()`` functions. This flag
- requires that :paramref:`.String.convert_unicode` is set to
- ``"force"`` - otherwise,
- SQLAlchemy is not guaranteed to handle the task of unicode
- conversion. Note that this flag adds significant performance
- overhead to row-fetching operations for backends that already
- return unicode objects natively (which most DBAPIs do). This
- flag should only be used as a last resort for reading
- strings from a column with varied or corrupted encodings.
+ the standard library's ``string.decode()`` functions, requires
+ that :paramref:`.String.convert_unicode` is set to
+ ``"force"``
"""
if unicode_error is not None and convert_unicode != "force":
@@ -225,8 +236,9 @@ class String(Concatenable, TypeEngine):
self.length = length
self.collation = collation
- self.convert_unicode = convert_unicode
- self.unicode_error = unicode_error
+ self._expect_unicode = convert_unicode or _expect_unicode
+ self._expect_unicode_error = unicode_error
+
self._warn_on_bytestring = _warn_on_bytestring
def literal_processor(self, dialect):
@@ -241,10 +253,10 @@ class String(Concatenable, TypeEngine):
return process
def bind_processor(self, dialect):
- if self.convert_unicode or dialect.convert_unicode:
+ if self._expect_unicode or dialect.convert_unicode:
if (
dialect.supports_unicode_binds
- and self.convert_unicode != "force"
+ and self._expect_unicode != "force"
):
if self._warn_on_bytestring:
@@ -266,7 +278,7 @@ class String(Concatenable, TypeEngine):
def process(value):
if isinstance(value, util.text_type):
- return encoder(value, self.unicode_error)[0]
+ return encoder(value, self._expect_unicode_error)[0]
elif warn_on_bytestring and value is not None:
util.warn_limited(
"Unicode type received non-unicode bind "
@@ -280,31 +292,31 @@ class String(Concatenable, TypeEngine):
return None
def result_processor(self, dialect, coltype):
- wants_unicode = self.convert_unicode or dialect.convert_unicode
+ wants_unicode = self._expect_unicode or dialect.convert_unicode
needs_convert = wants_unicode and (
dialect.returns_unicode_strings is not True
- or self.convert_unicode in ("force", "force_nocheck")
+ or self._expect_unicode in ("force", "force_nocheck")
)
needs_isinstance = (
needs_convert
and dialect.returns_unicode_strings
- and self.convert_unicode != "force_nocheck"
+ and self._expect_unicode != "force_nocheck"
)
if needs_convert:
if needs_isinstance:
return processors.to_conditional_unicode_processor_factory(
- dialect.encoding, self.unicode_error
+ dialect.encoding, self._expect_unicode_error
)
else:
return processors.to_unicode_processor_factory(
- dialect.encoding, self.unicode_error
+ dialect.encoding, self._expect_unicode_error
)
else:
return None
@property
def python_type(self):
- if self.convert_unicode:
+ if self._expect_unicode:
return util.text_type
else:
return str
@@ -312,6 +324,16 @@ class String(Concatenable, TypeEngine):
def get_dbapi_type(self, dbapi):
return dbapi.STRING
+ @classmethod
+ def _warn_deprecated_unicode(cls):
+ util.warn_deprecated(
+ "The convert_unicode on Engine and String as well as the "
+ "unicode_error flag on String are deprecated. All modern "
+ "DBAPIs now support Python Unicode natively under Python 2, and "
+ "under Python 3 all strings are inherently Unicode. These flags "
+ "will be removed in a future release."
+ )
+
class Text(String):
@@ -395,7 +417,7 @@ class Unicode(String):
defaults to ``True``.
"""
- kwargs.setdefault("convert_unicode", True)
+ kwargs.setdefault("_expect_unicode", True)
kwargs.setdefault("_warn_on_bytestring", True)
super(Unicode, self).__init__(length=length, **kwargs)
@@ -424,10 +446,13 @@ class UnicodeText(Text):
defaults to ``True``.
"""
- kwargs.setdefault("convert_unicode", True)
+ kwargs.setdefault("_expect_unicode", True)
kwargs.setdefault("_warn_on_bytestring", True)
super(UnicodeText, self).__init__(length=length, **kwargs)
+ def _warn_deprecated_unicode(self):
+ pass
+
class Integer(_LookupExpressionAdapter, TypeEngine):
@@ -697,11 +722,7 @@ class Float(Numeric):
scale = None
def __init__(
- self,
- precision=None,
- asdecimal=False,
- decimal_return_scale=None,
- **kwargs
+ self, precision=None, asdecimal=False, decimal_return_scale=None
):
r"""
Construct a Float.
@@ -724,25 +745,10 @@ class Float(Numeric):
.. versionadded:: 0.9.0
- :param \**kwargs:
-
- .. deprecated:: 0.9
-
- Additional keyword arguments are ignored by the base
- :class:`.Float` type, and keyword arguments will no longer
- be accepted in a future release. For database specific floats
- that support additional arguments, see that dialect's
- documentation for details, such as
- :class:`sqlalchemy.dialects.mysql.FLOAT`.
-
"""
self.precision = precision
self.asdecimal = asdecimal
self.decimal_return_scale = decimal_return_scale
- if kwargs:
- util.warn_deprecated(
- "Additional keyword arguments " "passed to Float ignored."
- )
def result_processor(self, dialect, coltype):
if self.asdecimal:
@@ -975,19 +981,13 @@ class LargeBinary(_Binary):
_Binary.__init__(self, length=length)
+@util.deprecated_cls(
+ "0.6",
+ "The :class:`.Binary` class is deprecated and will be removed "
+ "in a future relase. Please use :class:`.LargeBinary`.",
+)
class Binary(LargeBinary):
-
- """.. deprecated:: 0.6
-
- The :class:`.Binary` class is deprecated and will be removed
- in a future relase. Please use :class:`.LargeBinary`.
-
- """
-
def __init__(self, *arg, **kw):
- util.warn_deprecated(
- "The Binary type has been renamed to " "LargeBinary."
- )
LargeBinary.__init__(self, *arg, **kw)
@@ -1264,6 +1264,15 @@ class Enum(Emulated, String, SchemaType):
__visit_name__ = "enum"
+ @util.deprecated_params(
+ convert_unicode=(
+ "1.3",
+ "The :paramref:`.Enum.convert_unicode` parameter is deprecated "
+ "and will be removed in a future release. All modern DBAPIs "
+ "now support Python Unicode directly and this parameter is "
+ "unnecessary.",
+ )
+ )
def __init__(self, *enums, **kw):
r"""Construct an enum.
@@ -1376,11 +1385,15 @@ class Enum(Emulated, String, SchemaType):
if convert_unicode is None:
for e in self.enums:
+ # this is all py2k logic that can go away for py3k only,
+ # "expect unicode" will always be implicitly true
if isinstance(e, util.text_type):
- convert_unicode = True
+ _expect_unicode = True
break
else:
- convert_unicode = False
+ _expect_unicode = False
+ else:
+ _expect_unicode = convert_unicode
if self.enums:
length = max(len(x) for x in self.enums)
@@ -1389,7 +1402,7 @@ class Enum(Emulated, String, SchemaType):
self._valid_lookup[None] = self._object_lookup[None] = None
super(Enum, self).__init__(
- length=length, convert_unicode=convert_unicode
+ length=length, _expect_unicode=_expect_unicode
)
if self.enum_class:
@@ -1469,7 +1482,7 @@ class Enum(Emulated, String, SchemaType):
)
if op is operators.concat_op:
typ = String(
- self.type.length, convert_unicode=self.type.convert_unicode
+ self.type.length, _expect_unicode=self.type._expect_unicode
)
return op, typ
@@ -1491,7 +1504,7 @@ class Enum(Emulated, String, SchemaType):
)
def adapt_to_emulated(self, impltype, **kw):
- kw.setdefault("convert_unicode", self.convert_unicode)
+ kw.setdefault("_expect_unicode", self._expect_unicode)
kw.setdefault("validate_strings", self.validate_strings)
kw.setdefault("name", self.name)
kw.setdefault("schema", self.schema)
@@ -2205,7 +2218,7 @@ class JSON(Indexable, TypeEngine):
@util.memoized_property
def _str_impl(self):
- return String(convert_unicode=True)
+ return String(_expect_unicode=True)
def bind_processor(self, dialect):
string_process = self._str_impl.bind_processor(dialect)