summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-01-03 13:49:26 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2022-01-05 19:28:49 -0500
commit01c50c64e302c193733cef7fb146fbab8eaa44bd (patch)
treedca946206da557a14a681768d094b92c95dfabe4 /lib
parent146a349d81023805264f81643db50a5281da90da (diff)
downloadsqlalchemy-01c50c64e302c193733cef7fb146fbab8eaa44bd.tar.gz
Remove all remaining removed_in_20 warnings slated for removal
Finalize all remaining removed-in-2.0 changes so that we can begin doing pep-484 typing without old things getting in the way (we will also have to do public_factory). note there are a few "moved_in_20()" and "became_legacy_in_20()" warnings still in place. The SQLALCHEMY_WARN_20 variable is now removed. Also removed here are the legacy "in place mutators" for Select statements, and some keyword-only argument signatures in Core have been added. Also in the big change department, the ORM mapper() function is removed entirely; the Mapper class is otherwise unchanged, just the public-facing API function. Mappers are now always given a registry in which to participate, however the argument signature of Mapper is not changed. ideally "registry" would be the first positional argument. Fixes: #7257 Change-Id: Ic70c57b9f1cf7eb996338af5183b11bdeb3e1623
Diffstat (limited to 'lib')
-rw-r--r--lib/sqlalchemy/dialects/mysql/enumerated.py17
-rw-r--r--lib/sqlalchemy/engine/reflection.py11
-rw-r--r--lib/sqlalchemy/exc.py6
-rw-r--r--lib/sqlalchemy/ext/declarative/__init__.py1
-rw-r--r--lib/sqlalchemy/ext/declarative/extensions.py19
-rw-r--r--lib/sqlalchemy/ext/mutable.py5
-rw-r--r--lib/sqlalchemy/orm/__init__.py37
-rw-r--r--lib/sqlalchemy/orm/context.py26
-rw-r--r--lib/sqlalchemy/orm/decl_api.py23
-rw-r--r--lib/sqlalchemy/orm/events.py48
-rw-r--r--lib/sqlalchemy/orm/loading.py3
-rw-r--r--lib/sqlalchemy/orm/mapper.py24
-rw-r--r--lib/sqlalchemy/orm/query.py16
-rw-r--r--lib/sqlalchemy/orm/relationships.py28
-rw-r--r--lib/sqlalchemy/orm/session.py144
-rw-r--r--lib/sqlalchemy/orm/unitofwork.py26
-rw-r--r--lib/sqlalchemy/orm/util.py18
-rw-r--r--lib/sqlalchemy/sql/coercions.py20
-rw-r--r--lib/sqlalchemy/sql/dml.py165
-rw-r--r--lib/sqlalchemy/sql/elements.py22
-rw-r--r--lib/sqlalchemy/sql/schema.py8
-rw-r--r--lib/sqlalchemy/sql/selectable.py414
-rw-r--r--lib/sqlalchemy/sql/sqltypes.py19
-rw-r--r--lib/sqlalchemy/testing/assertions.py10
-rw-r--r--lib/sqlalchemy/testing/profiling.py17
-rw-r--r--lib/sqlalchemy/testing/warnings.py7
-rw-r--r--lib/sqlalchemy/util/__init__.py5
-rw-r--r--lib/sqlalchemy/util/deprecations.py87
28 files changed, 195 insertions, 1031 deletions
diff --git a/lib/sqlalchemy/dialects/mysql/enumerated.py b/lib/sqlalchemy/dialects/mysql/enumerated.py
index b84608f58..f92e2cf19 100644
--- a/lib/sqlalchemy/dialects/mysql/enumerated.py
+++ b/lib/sqlalchemy/dialects/mysql/enumerated.py
@@ -12,7 +12,6 @@ from ... import exc
from ... import sql
from ... import util
from ...sql import sqltypes
-from ...sql.base import NO_ARG
class ENUM(sqltypes.NativeForEmulated, sqltypes.Enum, _StringType):
@@ -59,15 +58,7 @@ class ENUM(sqltypes.NativeForEmulated, sqltypes.Enum, _StringType):
BINARY in schema. This does not affect the type of data stored,
only the collation of character data.
- :param quoting: Not used. A warning will be raised if provided.
-
"""
- if kw.pop("quoting", NO_ARG) is not NO_ARG:
- util.warn_deprecated_20(
- "The 'quoting' parameter to :class:`.mysql.ENUM` is deprecated"
- " and will be removed in a future release. "
- "This parameter now has no effect."
- )
kw.pop("strict", None)
self._enum_init(enums, kw)
_StringType.__init__(self, length=self.length, **kw)
@@ -151,15 +142,7 @@ class SET(_StringType):
.. versionadded:: 1.0.0
- :param quoting: Not used. A warning will be raised if passed.
-
"""
- if kw.pop("quoting", NO_ARG) is not NO_ARG:
- util.warn_deprecated_20(
- "The 'quoting' parameter to :class:`.mysql.SET` is deprecated"
- " and will be removed in a future release. "
- "This parameter now has no effect."
- )
self.retrieve_as_bitwise = kw.pop("retrieve_as_bitwise", False)
self.values = tuple(values)
if not self.retrieve_as_bitwise and "" in values:
diff --git a/lib/sqlalchemy/engine/reflection.py b/lib/sqlalchemy/engine/reflection.py
index e1b06a314..92c243de3 100644
--- a/lib/sqlalchemy/engine/reflection.py
+++ b/lib/sqlalchemy/engine/reflection.py
@@ -681,17 +681,6 @@ class Inspector:
conn, table_name, schema, info_cache=self.info_cache, **kw
)
- @util.deprecated_20(
- ":meth:`_reflection.Inspector.reflecttable`",
- "The :meth:`_reflection.Inspector.reflecttable` "
- "method was renamed to "
- ":meth:`_reflection.Inspector.reflect_table`. This deprecated alias "
- "will be removed in a future release.",
- )
- def reflecttable(self, *args, **kwargs):
- "See reflect_table. This method name is deprecated"
- return self.reflect_table(*args, **kwargs)
-
def reflect_table(
self,
table,
diff --git a/lib/sqlalchemy/exc.py b/lib/sqlalchemy/exc.py
index e51214fd9..77edf98a0 100644
--- a/lib/sqlalchemy/exc.py
+++ b/lib/sqlalchemy/exc.py
@@ -705,11 +705,7 @@ class LegacyAPIWarning(Base20DeprecationWarning):
"""indicates an API that is in 'legacy' status, a long term deprecation."""
-class RemovedIn20Warning(Base20DeprecationWarning):
- """indicates an API that will be fully removed in SQLAlchemy 2.0."""
-
-
-class MovedIn20Warning(RemovedIn20Warning):
+class MovedIn20Warning(Base20DeprecationWarning):
"""Subtype of RemovedIn20Warning to indicate an API that moved only."""
diff --git a/lib/sqlalchemy/ext/declarative/__init__.py b/lib/sqlalchemy/ext/declarative/__init__.py
index b1c1d3691..ebb992742 100644
--- a/lib/sqlalchemy/ext/declarative/__init__.py
+++ b/lib/sqlalchemy/ext/declarative/__init__.py
@@ -8,7 +8,6 @@
from .extensions import AbstractConcreteBase
from .extensions import ConcreteBase
from .extensions import DeferredReflection
-from .extensions import instrument_declarative
from ... import util
from ...orm.decl_api import as_declarative as _as_declarative
from ...orm.decl_api import declarative_base as _declarative_base
diff --git a/lib/sqlalchemy/ext/declarative/extensions.py b/lib/sqlalchemy/ext/declarative/extensions.py
index 1862592f5..b7c0e78d9 100644
--- a/lib/sqlalchemy/ext/declarative/extensions.py
+++ b/lib/sqlalchemy/ext/declarative/extensions.py
@@ -8,9 +8,7 @@
from ... import inspection
-from ... import util
from ...orm import exc as orm_exc
-from ...orm import registry
from ...orm import relationships
from ...orm.base import _mapper_or_none
from ...orm.clsregistry import _resolver
@@ -20,23 +18,6 @@ from ...schema import Table
from ...util import OrderedDict
-@util.deprecated(
- "2.0",
- "the instrument_declarative function is deprecated "
- "and will be removed in SQLAlhcemy 2.0. Please use "
- ":meth:`_orm.registry.map_declaratively",
-)
-def instrument_declarative(cls, cls_registry, metadata):
- """Given a class, configure the class declaratively,
- using the given registry, which can be any dictionary, and
- MetaData object.
-
- """
- registry(metadata=metadata, class_registry=cls_registry).map_declaratively(
- cls
- )
-
-
class ConcreteBase:
"""A helper class for 'concrete' declarative mappings.
diff --git a/lib/sqlalchemy/ext/mutable.py b/lib/sqlalchemy/ext/mutable.py
index 7e277d379..7a497abfc 100644
--- a/lib/sqlalchemy/ext/mutable.py
+++ b/lib/sqlalchemy/ext/mutable.py
@@ -360,7 +360,6 @@ from .. import event
from .. import inspect
from .. import types
from ..orm import Mapper
-from ..orm import mapper
from ..orm.attributes import flag_modified
from ..sql.base import SchemaEventTarget
from ..util import memoized_property
@@ -567,7 +566,7 @@ class Mutable(MutableBase):
if isinstance(prop.columns[0].type, sqltype):
cls.associate_with_attribute(getattr(class_, prop.key))
- event.listen(mapper, "mapper_configured", listen_for_type)
+ event.listen(Mapper, "mapper_configured", listen_for_type)
@classmethod
def as_mutable(cls, sqltype):
@@ -629,7 +628,7 @@ class Mutable(MutableBase):
) or (prop.columns[0].type is sqltype):
cls.associate_with_attribute(getattr(class_, prop.key))
- event.listen(mapper, "mapper_configured", listen_for_type)
+ event.listen(Mapper, "mapper_configured", listen_for_type)
return sqltype
diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py
index 69a3e64da..50b320cb2 100644
--- a/lib/sqlalchemy/orm/__init__.py
+++ b/lib/sqlalchemy/orm/__init__.py
@@ -100,6 +100,7 @@ from .util import with_parent
from .util import with_polymorphic
from .. import sql as _sql
from .. import util as _sa_util
+from ..exc import InvalidRequestError
from ..util.langhelpers import public_factory
@@ -144,11 +145,31 @@ with_loader_criteria = public_factory(LoaderCriteriaOption, ".orm")
relationship = public_factory(RelationshipProperty, ".orm.relationship")
-@_sa_util.deprecated_20("relation", "Please use :func:`.relationship`.")
-def relation(*arg, **kw):
- """A synonym for :func:`relationship`."""
+def mapper(*arg, **kw):
+ """Placeholder for the now-removed ``mapper()`` function.
- return relationship(*arg, **kw)
+ Classical mappings should be performed using the
+ :meth:`_orm.registry.map_imperatively` method.
+
+ This symbol remains in SQLAlchemy 2.0 to suit the deprecated use case
+ of using the ``mapper()`` function as a target for ORM event listeners,
+ which failed to be marked as deprecated in the 1.4 series.
+
+ Global ORM mapper listeners should instead use the :class:`_orm.Mapper`
+ class as the target.
+
+ .. versionchanged:: 2.0 The ``mapper()`` function was removed; the
+ symbol remains temporarily as a placeholder for the event listening
+ use case.
+
+ """
+ raise InvalidRequestError(
+ "The 'sqlalchemy.orm.mapper()' function is removed as of "
+ "SQLAlchemy 2.0. Use the "
+ "'sqlalchemy.orm.registry.map_imperatively()` "
+ "method of the ``sqlalchemy.orm.registry`` class to perform "
+ "classical mapping."
+ )
def dynamic_loader(argument, **kw):
@@ -251,8 +272,6 @@ def query_expression(default_expr=_sql.null()):
return prop
-mapper = public_factory(Mapper, ".orm.mapper")
-
synonym = public_factory(SynonymProperty, ".orm.synonym")
@@ -284,12 +303,6 @@ def clear_mappers():
mapperlib._dispose_registries(mapperlib._all_registries(), False)
-@_sa_util.deprecated_20("eagerload", "Please use :func:`_orm.joinedload`.")
-def eagerload(*args, **kwargs):
- """A synonym for :func:`joinedload()`."""
- return joinedload(*args, **kwargs)
-
-
contains_alias = public_factory(AliasOption, ".orm.contains_alias")
if True:
diff --git a/lib/sqlalchemy/orm/context.py b/lib/sqlalchemy/orm/context.py
index 012db36c2..36590f8ee 100644
--- a/lib/sqlalchemy/orm/context.py
+++ b/lib/sqlalchemy/orm/context.py
@@ -1091,24 +1091,6 @@ class ORMSelectCompileState(ORMCompileState, SelectState):
def _simple_statement(self):
- if (
- self.compile_options._use_legacy_query_style
- and (self.distinct and not self.distinct_on)
- and self.order_by
- ):
- to_add = sql_util.expand_column_list_from_order_by(
- self.primary_columns, self.order_by
- )
- if to_add:
- util.warn_deprecated_20(
- "ORDER BY columns added implicitly due to "
- "DISTINCT is deprecated and will be removed in "
- "SQLAlchemy 2.0. SELECT statements with DISTINCT "
- "should be written to explicitly include the appropriate "
- "columns in the columns clause"
- )
- self.primary_columns += to_add
-
statement = self._select_statement(
self.primary_columns + self.secondary_columns,
tuple(self.from_clauses) + tuple(self.eager_joins.values()),
@@ -2293,14 +2275,6 @@ class _BundleEntity(_QueryEntity):
)
self.supports_single_entity = self.bundle.single_entity
- if (
- self.supports_single_entity
- and not compile_state.compile_options._use_legacy_query_style
- ):
- util.warn_deprecated_20(
- "The Bundle.single_entity flag has no effect when "
- "using 2.0 style execution."
- )
@property
def mapper(self):
diff --git a/lib/sqlalchemy/orm/decl_api.py b/lib/sqlalchemy/orm/decl_api.py
index 7b6814863..c973f5a4c 100644
--- a/lib/sqlalchemy/orm/decl_api.py
+++ b/lib/sqlalchemy/orm/decl_api.py
@@ -370,7 +370,7 @@ def declarative_base(
The new base class will be given a metaclass that produces
appropriate :class:`~sqlalchemy.schema.Table` objects and makes
- the appropriate :func:`~sqlalchemy.orm.mapper` calls based on the
+ the appropriate :class:`_orm.Mapper` calls based on the
information provided declaratively in the class and any subclasses
of the class.
@@ -408,7 +408,7 @@ def declarative_base(
``metadata`` attribute of the generated declarative base class.
:param mapper:
- An optional callable, defaults to :func:`~sqlalchemy.orm.mapper`. Will
+ An optional callable, defaults to :class:`_orm.Mapper`. Will
be used to map subclasses to their Tables.
:param cls:
@@ -479,8 +479,8 @@ class registry:
* :meth:`_orm.registry.map_imperatively` will produce a
:class:`_orm.Mapper` for a class without scanning the class for
declarative class attributes. This method suits the use case historically
- provided by the
- :func:`_orm.mapper` classical mapping function.
+ provided by the ``sqlalchemy.orm.mapper()`` classical mapping function,
+ which is removed as of SQLAlchemy 2.0.
.. versionadded:: 1.4
@@ -749,7 +749,7 @@ class registry:
examples.
:param mapper:
- An optional callable, defaults to :func:`~sqlalchemy.orm.mapper`.
+ An optional callable, defaults to :class:`_orm.Mapper`.
This function is used to generate new :class:`_orm.Mapper` objects.
:param cls:
@@ -923,8 +923,8 @@ class registry:
information. Instead, all mapping constructs are passed as
arguments.
- This method is intended to be fully equivalent to the classic
- SQLAlchemy :func:`_orm.mapper` function, except that it's in terms of
+ This method is intended to be fully equivalent to the now-removed
+ SQLAlchemy ``mapper()`` function, except that it's in terms of
a particular registry.
E.g.::
@@ -948,15 +948,15 @@ class registry:
and usage examples.
:param class\_: The class to be mapped. Corresponds to the
- :paramref:`_orm.mapper.class_` parameter.
+ :paramref:`_orm.Mapper.class_` parameter.
:param local_table: the :class:`_schema.Table` or other
:class:`_sql.FromClause` object that is the subject of the mapping.
Corresponds to the
- :paramref:`_orm.mapper.local_table` parameter.
+ :paramref:`_orm.Mapper.local_table` parameter.
:param \**kw: all other keyword arguments are passed to the
- :func:`_orm.mapper` function directly.
+ :class:`_orm.Mapper` constructor directly.
.. seealso::
@@ -968,9 +968,6 @@ class registry:
return _mapper(self, class_, local_table, kw)
-mapperlib._legacy_registry = registry()
-
-
def as_declarative(**kw):
"""
Class decorator which will adapt a given class into a
diff --git a/lib/sqlalchemy/orm/events.py b/lib/sqlalchemy/orm/events.py
index a66bf64d8..03e3796a6 100644
--- a/lib/sqlalchemy/orm/events.py
+++ b/lib/sqlalchemy/orm/events.py
@@ -152,8 +152,8 @@ class InstanceEvents(event.Events):
* unmapped superclasses of mapped or to-be-mapped classes
(using the ``propagate=True`` flag)
* :class:`_orm.Mapper` objects
- * the :class:`_orm.Mapper` class itself and the :func:`.mapper`
- function indicate listening for all mappers.
+ * the :class:`_orm.Mapper` class itself indicates listening for all
+ mappers.
Instance events are closely related to mapper events, but
are more specific to the instance and its instrumentation,
@@ -200,6 +200,12 @@ class InstanceEvents(event.Events):
elif isinstance(target, mapperlib.Mapper):
return target.class_manager
elif target is orm.mapper:
+ util.warn_deprecated(
+ "The `sqlalchemy.orm.mapper()` symbol is deprecated and "
+ "will be removed in a future release. For the mapper-wide "
+ "event target, use the 'sqlalchemy.orm.Mapper' class.",
+ "2.0",
+ )
return instrumentation.ClassManager
elif isinstance(target, type):
if issubclass(target, mapperlib.Mapper):
@@ -638,8 +644,8 @@ class MapperEvents(event.Events):
* unmapped superclasses of mapped or to-be-mapped classes
(using the ``propagate=True`` flag)
* :class:`_orm.Mapper` objects
- * the :class:`_orm.Mapper` class itself and the :func:`.mapper`
- function indicate listening for all mappers.
+ * the :class:`_orm.Mapper` class itself indicates listening for all
+ mappers.
Mapper events provide hooks into critical sections of the
mapper, including those related to object instrumentation,
@@ -692,6 +698,12 @@ class MapperEvents(event.Events):
orm = util.preloaded.orm
if target is orm.mapper:
+ util.warn_deprecated(
+ "The `sqlalchemy.orm.mapper()` symbol is deprecated and "
+ "will be removed in a future release. For the mapper-wide "
+ "event target, use the 'sqlalchemy.orm.Mapper' class.",
+ "2.0",
+ )
return mapperlib.Mapper
elif isinstance(target, type):
if issubclass(target, mapperlib.Mapper):
@@ -721,7 +733,7 @@ class MapperEvents(event.Events):
):
util.warn(
"'before_configured' and 'after_configured' ORM events "
- "only invoke with the mapper() function or Mapper class "
+ "only invoke with the Mapper class "
"as the target."
)
@@ -896,13 +908,13 @@ class MapperEvents(event.Events):
new mappers have been made available and new mapper use is
detected.
- This event can **only** be applied to the :class:`_orm.Mapper` class
- or :func:`.mapper` function, and not to individual mappings or
- mapped classes. It is only invoked for all mappings as a whole::
+ This event can **only** be applied to the :class:`_orm.Mapper` class,
+ and not to individual mappings or mapped classes. It is only invoked
+ for all mappings as a whole::
- from sqlalchemy.orm import mapper
+ from sqlalchemy.orm import Mapper
- @event.listens_for(mapper, "before_configured")
+ @event.listens_for(Mapper, "before_configured")
def go():
# ...
@@ -959,13 +971,13 @@ class MapperEvents(event.Events):
Also contrast to :meth:`.MapperEvents.before_configured`,
which is invoked before the series of mappers has been configured.
- This event can **only** be applied to the :class:`_orm.Mapper` class
- or :func:`.mapper` function, and not to individual mappings or
+ This event can **only** be applied to the :class:`_orm.Mapper` class,
+ and not to individual mappings or
mapped classes. It is only invoked for all mappings as a whole::
- from sqlalchemy.orm import mapper
+ from sqlalchemy.orm import Mapper
- @event.listens_for(mapper, "after_configured")
+ @event.listens_for(Mapper, "after_configured")
def go():
# ...
@@ -1005,7 +1017,7 @@ class MapperEvents(event.Events):
The event is often called for a batch of objects of the
same class before their INSERT statements are emitted at
once in a later step. In the extremely rare case that
- this is not desirable, the :func:`.mapper` can be
+ this is not desirable, the :class:`_orm.Mapper` object can be
configured with ``batch=False``, which will cause
batches of instances to be broken up into individual
(and more poorly performing) event->persist->event
@@ -1052,7 +1064,7 @@ class MapperEvents(event.Events):
same class after their INSERT statements have been
emitted at once in a previous step. In the extremely
rare case that this is not desirable, the
- :func:`.mapper` can be configured with ``batch=False``,
+ :class:`_orm.Mapper` object can be configured with ``batch=False``,
which will cause batches of instances to be broken up
into individual (and more poorly performing)
event->persist->event steps.
@@ -1116,7 +1128,7 @@ class MapperEvents(event.Events):
The event is often called for a batch of objects of the
same class before their UPDATE statements are emitted at
once in a later step. In the extremely rare case that
- this is not desirable, the :func:`.mapper` can be
+ this is not desirable, the :class:`_orm.Mapper` can be
configured with ``batch=False``, which will cause
batches of instances to be broken up into individual
(and more poorly performing) event->persist->event
@@ -1180,7 +1192,7 @@ class MapperEvents(event.Events):
The event is often called for a batch of objects of the
same class after their UPDATE statements have been emitted at
once in a previous step. In the extremely rare case that
- this is not desirable, the :func:`.mapper` can be
+ this is not desirable, the :class:`_orm.Mapper` can be
configured with ``batch=False``, which will cause
batches of instances to be broken up into individual
(and more poorly performing) event->persist->event
diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py
index 047971d35..796003ebb 100644
--- a/lib/sqlalchemy/orm/loading.py
+++ b/lib/sqlalchemy/orm/loading.py
@@ -262,11 +262,10 @@ def merge_frozen_result(session, statement, frozen_result, load=True):
session.autoflush = autoflush
-@util.deprecated_20(
+@util.became_legacy_20(
":func:`_orm.merge_result`",
alternative="The function as well as the method on :class:`_orm.Query` "
"is superseded by the :func:`_orm.merge_frozen_result` function.",
- becomes_legacy=True,
)
@util.preload_module("sqlalchemy.orm.context")
def merge_result(query, iterator, load=True):
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index 21da7c2f3..bc818559d 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -57,8 +57,6 @@ from ..util import HasMemoized
_mapper_registries = weakref.WeakKeyDictionary()
-_legacy_registry = None
-
def _all_registries():
with _CONFIGURE_MUTEX:
@@ -148,16 +146,15 @@ class Mapper(
):
r"""Direct constructor for a new :class:`_orm.Mapper` object.
- The :func:`_orm.mapper` function is normally invoked through the
+ The :class:`_orm.Mapper` constructor is not called directly, and
+ is normally invoked through the
use of the :class:`_orm.registry` object through either the
:ref:`Declarative <orm_declarative_mapping>` or
:ref:`Imperative <orm_imperative_mapping>` mapping styles.
- .. versionchanged:: 1.4 The :func:`_orm.mapper` function should not
- be called directly for classical mapping; for a classical mapping
- configuration, use the :meth:`_orm.registry.map_imperatively`
- method. The :func:`_orm.mapper` function may become private in a
- future release.
+ .. versionchanged:: 2.0 The public facing ``mapper()`` function is
+ removed; for a classical mapping configuration, use the
+ :meth:`_orm.registry.map_imperatively` method.
Parameters documented below may be passed to either the
:meth:`_orm.registry.map_imperatively` method, or may be passed in the
@@ -1202,8 +1199,7 @@ class Mapper(
# we expect that declarative has applied the class manager
# already and set up a registry. if this is None,
- # we will emit a deprecation warning below when we also see that
- # it has no registry.
+ # this raises as of 2.0.
manager = attributes.manager_of_class(self.class_)
if self.non_primary:
@@ -1251,14 +1247,12 @@ class Mapper(
)
if not manager.registry:
- util.warn_deprecated_20(
- "Calling the mapper() function directly outside of a "
- "declarative registry is deprecated."
+ raise sa_exc.InvalidRequestError(
+ "The _mapper() function may not be invoked directly outside "
+ "of a declarative registry."
" Please use the sqlalchemy.orm.registry.map_imperatively() "
"function for a classical mapping."
)
- assert _legacy_registry is not None
- _legacy_registry._add_manager(manager)
self.class_manager = manager
self.registry = manager.registry
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index 2d574c6b2..e8ec5f156 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -677,7 +677,7 @@ class Query(
self._compile_options += opt
return self
- @util.deprecated_20(
+ @util.became_legacy_20(
":meth:`_orm.Query.with_labels` and :meth:`_orm.Query.apply_labels`",
alternative="Use set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) "
"instead.",
@@ -803,10 +803,9 @@ class Query(
self.load_options += {"_yield_per": count}
return self
- @util.deprecated_20(
+ @util.became_legacy_20(
":meth:`_orm.Query.get`",
alternative="The method is now available as :meth:`_orm.Session.get`",
- becomes_legacy=True,
)
def get(self, ident):
"""Return an instance based on the given primary key identifier,
@@ -933,8 +932,8 @@ class Query(
:func:`~.expression.select`.
The method here accepts mapped classes, :func:`.aliased` constructs,
- and :func:`.mapper` constructs as arguments, which are resolved into
- expression constructs, in addition to appropriate expression
+ and :class:`_orm.Mapper` constructs as arguments, which are resolved
+ into expression constructs, in addition to appropriate expression
constructs.
The correlation arguments are ultimately passed to
@@ -997,10 +996,9 @@ class Query(
self.load_options += {"_invoke_all_eagers": value}
return self
- @util.deprecated_20(
+ @util.became_legacy_20(
":meth:`_orm.Query.with_parent`",
alternative="Use the :func:`_orm.with_parent` standalone construct.",
- becomes_legacy=True,
)
@util.preload_module("sqlalchemy.orm.relationships")
def with_parent(self, instance, property=None, from_entity=None): # noqa
@@ -2046,7 +2044,6 @@ class Query(
return orm_util._getitem(
self,
item,
- allow_negative=not self.session or not self.session.future,
)
@_generative
@@ -2405,11 +2402,10 @@ class Query(
return result
- @util.deprecated_20(
+ @util.became_legacy_20(
":meth:`_orm.Query.merge_result`",
alternative="The method is superseded by the "
":func:`_orm.merge_frozen_result` function.",
- becomes_legacy=True,
enable_warnings=False, # warnings occur via loading.merge_result
)
def merge_result(self, iterator, load=True):
diff --git a/lib/sqlalchemy/orm/relationships.py b/lib/sqlalchemy/orm/relationships.py
index dd58c0201..522947cc5 100644
--- a/lib/sqlalchemy/orm/relationships.py
+++ b/lib/sqlalchemy/orm/relationships.py
@@ -111,7 +111,7 @@ class RelationshipProperty(StrategizedProperty):
passive_updates=True,
enable_typechecks=True,
active_history=False,
- cascade_backrefs=True,
+ cascade_backrefs=False,
)
_dependency_processor = None
@@ -403,21 +403,11 @@ class RelationshipProperty(StrategizedProperty):
:ref:`tutorial_delete_cascade` - Tutorial example describing
a delete cascade.
- :param cascade_backrefs=True:
- A boolean value indicating if the ``save-update`` cascade should
- operate along an assignment event intercepted by a backref.
- When set to ``False``, the attribute managed by this relationship
- will not cascade an incoming transient object into the session of a
- persistent parent, if the event is received via backref.
+ :param cascade_backrefs=False:
+ Legacy; this flag is always False.
- .. deprecated:: 1.4 The
- :paramref:`_orm.relationship.cascade_backrefs`
- flag will default to False in all cases in SQLAlchemy 2.0.
-
- .. seealso::
-
- :ref:`backref_cascade` - Full discussion and examples on how
- the :paramref:`_orm.relationship.cascade_backrefs` option is used.
+ .. versionchanged:: 2.0 "cascade_backrefs" functionality has been
+ removed.
:param collection_class:
A class or callable that returns a new list-holding object. will
@@ -1007,7 +997,13 @@ class RelationshipProperty(StrategizedProperty):
self._user_defined_foreign_keys = foreign_keys
self.collection_class = collection_class
self.passive_deletes = passive_deletes
- self.cascade_backrefs = cascade_backrefs
+
+ if cascade_backrefs:
+ raise sa_exc.ArgumentError(
+ "The 'cascade_backrefs' parameter passed to "
+ "relationship() may only be set to False."
+ )
+
self.passive_updates = passive_updates
self.remote_side = remote_side
self.enable_typechecks = enable_typechecks
diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py
index 62e560475..b1b7005fe 100644
--- a/lib/sqlalchemy/orm/session.py
+++ b/lib/sqlalchemy/orm/session.py
@@ -985,7 +985,7 @@ class Session(_SessionClassMethods):
self,
bind=None,
autoflush=True,
- future=False,
+ future=True,
expire_on_commit=True,
twophase=False,
binds=None,
@@ -1074,20 +1074,7 @@ class Session(_SessionClassMethods):
:ref:`session_committing`
- :param future: if True, use 2.0 style transactional and engine
- behavior. Future mode includes the following behaviors:
-
- * The :class:`_orm.Session` will not use "bound" metadata in order
- to locate an :class:`_engine.Engine`; the engine or engines in use
- must be specified to the constructor of :class:`_orm.Session` or
- otherwise be configured against the :class:`_orm.sessionmaker`
- in use
-
- * The behavior of the :paramref:`_orm.relationship.cascade_backrefs`
- flag on a :func:`_orm.relationship` will always assume
- "False" behavior.
-
- .. versionadded:: 1.4
+ :param future: Deprecated; this flag is always True.
.. seealso::
@@ -1128,6 +1115,12 @@ class Session(_SessionClassMethods):
)
self.identity_map = identity.WeakInstanceDict()
+ if not future:
+ raise sa_exc.ArgumentError(
+ "The 'future' parameter passed to "
+ "Session() may only be set to True."
+ )
+
self._new = {} # InstanceState->object, strong refs object
self._deleted = {} # same
self.bind = bind
@@ -1136,7 +1129,6 @@ class Session(_SessionClassMethods):
self._warn_on_events = False
self._transaction = None
self._nested_transaction = None
- self.future = future
self.hash_key = _new_sessionid()
self.autoflush = autoflush
self.expire_on_commit = expire_on_commit
@@ -1170,33 +1162,6 @@ class Session(_SessionClassMethods):
with self.begin():
yield self
- @property
- @util.deprecated_20(
- ":attr:`_orm.Session.transaction`",
- alternative="For context manager use, use "
- ":meth:`_orm.Session.begin`. To access "
- "the current root transaction, use "
- ":meth:`_orm.Session.get_transaction`.",
- warn_on_attribute_access=True,
- )
- def transaction(self):
- """The current active or inactive :class:`.SessionTransaction`.
-
- May be None if no transaction has begun yet.
-
- .. versionchanged:: 1.4 the :attr:`.Session.transaction` attribute
- is now a read-only descriptor that also may return None if no
- transaction has begun yet.
-
-
- """
- return self._legacy_transaction()
-
- def _legacy_transaction(self):
- if not self.future:
- self._autobegin()
- return self._transaction
-
def in_transaction(self):
"""Return True if this :class:`_orm.Session` has begun a transaction.
@@ -1350,13 +1315,7 @@ class Session(_SessionClassMethods):
If no transaction is in progress, this method is a pass-through.
- In :term:`1.x-style` use, this method rolls back the topmost
- database transaction if no nested transactions are in effect, or
- to the current nested transaction if one is in effect.
-
- When
- :term:`2.0-style` use is in effect via the
- :paramref:`_orm.Session.future` flag, the method always rolls back
+ The method always rolls back
the topmost database transaction, discarding any nested
transactions that may be in progress.
@@ -1370,7 +1329,7 @@ class Session(_SessionClassMethods):
if self._transaction is None:
pass
else:
- self._transaction.rollback(_to_root=self.future)
+ self._transaction.rollback(_to_root=True)
def commit(self):
"""Flush pending changes and commit the current transaction.
@@ -1378,15 +1337,8 @@ class Session(_SessionClassMethods):
If no transaction is in progress, the method will first
"autobegin" a new transaction and commit.
- If :term:`1.x-style` use is in effect and there are currently
- SAVEPOINTs in progress via :meth:`_orm.Session.begin_nested`,
- the operation will release the current SAVEPOINT but not commit
- the outermost database transaction.
-
- If :term:`2.0-style` use is in effect via the
- :paramref:`_orm.Session.future` flag, the outermost database
- transaction is committed unconditionally, automatically releasing any
- SAVEPOINTs in effect.
+ The outermost database transaction is committed unconditionally,
+ automatically releasing any SAVEPOINTs in effect.
.. seealso::
@@ -1399,7 +1351,7 @@ class Session(_SessionClassMethods):
if not self._autobegin():
raise sa_exc.InvalidRequestError("No transaction is begun.")
- self._transaction.commit(_to_root=self.future)
+ self._transaction.commit(_to_root=True)
def prepare(self):
"""Prepare the current transaction in progress for two phase commit.
@@ -1418,7 +1370,7 @@ class Session(_SessionClassMethods):
self._transaction.prepare()
- def connection(self, bind_arguments=None, execution_options=None, **kw):
+ def connection(self, bind_arguments=None, execution_options=None):
r"""Return a :class:`_engine.Connection` object corresponding to this
:class:`.Session` object's transactional state.
@@ -1437,15 +1389,6 @@ class Session(_SessionClassMethods):
"mapper", "bind", "clause", other custom arguments that are passed
to :meth:`.Session.get_bind`.
- :param bind:
- deprecated; use bind_arguments
-
- :param mapper:
- deprecated; use bind_arguments
-
- :param clause:
- deprecated; use bind_arguments
-
:param execution_options: a dictionary of execution options that will
be passed to :meth:`_engine.Connection.execution_options`, **when the
connection is first procured only**. If the connection is already
@@ -1456,17 +1399,15 @@ class Session(_SessionClassMethods):
:ref:`session_transaction_isolation`
- :param \**kw:
- deprecated; use bind_arguments
-
"""
- if not bind_arguments:
- bind_arguments = kw
+ if bind_arguments:
+ bind = bind_arguments.pop("bind", None)
- bind = bind_arguments.pop("bind", None)
- if bind is None:
- bind = self.get_bind(**bind_arguments)
+ if bind is None:
+ bind = self.get_bind(**bind_arguments)
+ else:
+ bind = self.get_bind()
return self._connection_for_bind(
bind,
@@ -1490,7 +1431,6 @@ class Session(_SessionClassMethods):
bind_arguments=None,
_parent_execute_state=None,
_add_event=None,
- **kw,
):
r"""Execute a SQL expression construct.
@@ -1505,8 +1445,8 @@ class Session(_SessionClassMethods):
)
The API contract of :meth:`_orm.Session.execute` is similar to that
- of :meth:`_future.Connection.execute`, the :term:`2.0 style` version
- of :class:`_future.Connection`.
+ of :meth:`_engine.Connection.execute`, the :term:`2.0 style` version
+ of :class:`_engine.Connection`.
.. versionchanged:: 1.4 the :meth:`_orm.Session.execute` method is
now the primary point of ORM statement execution when using
@@ -1539,32 +1479,13 @@ class Session(_SessionClassMethods):
Contents of this dictionary are passed to the
:meth:`.Session.get_bind` method.
- :param mapper:
- deprecated; use the bind_arguments dictionary
-
- :param bind:
- deprecated; use the bind_arguments dictionary
-
- :param \**kw:
- deprecated; use the bind_arguments dictionary
-
:return: a :class:`_engine.Result` object.
"""
statement = coercions.expect(roles.StatementRole, statement)
- if kw:
- util.warn_deprecated_20(
- "Passing bind arguments to Session.execute() as keyword "
- "arguments is deprecated and will be removed SQLAlchemy 2.0. "
- "Please use the bind_arguments parameter."
- )
- if not bind_arguments:
- bind_arguments = kw
- else:
- bind_arguments.update(kw)
- elif not bind_arguments:
+ if not bind_arguments:
bind_arguments = {}
if (
@@ -1848,7 +1769,7 @@ class Session(_SessionClassMethods):
mapped.
:param bind: an :class:`_engine.Engine` or :class:`_engine.Connection`
- object.
+ object.
.. seealso::
@@ -1913,15 +1834,12 @@ class Session(_SessionClassMethods):
:ref:`session_custom_partitioning`.
:param mapper:
- Optional :func:`.mapper` mapped class or instance of
- :class:`_orm.Mapper`. The bind can be derived from a
- :class:`_orm.Mapper`
- first by consulting the "binds" map associated with this
- :class:`.Session`, and secondly by consulting the
- :class:`_schema.MetaData`
- associated with the :class:`_schema.Table` to which the
- :class:`_orm.Mapper`
- is mapped for a bind.
+ Optional mapped class or corresponding :class:`_orm.Mapper` instance.
+ The bind can be derived from a :class:`_orm.Mapper` first by
+ consulting the "binds" map associated with this :class:`.Session`,
+ and secondly by consulting the :class:`_schema.MetaData` associated
+ with the :class:`_schema.Table` to which the :class:`_orm.Mapper` is
+ mapped for a bind.
:param clause:
A :class:`_expression.ClauseElement` (i.e.
@@ -2587,7 +2505,7 @@ class Session(_SessionClassMethods):
)
.. versionadded:: 1.4 Added :meth:`_orm.Session.get`, which is moved
- from the now deprecated :meth:`_orm.Query.get` method.
+ from the now legacy :meth:`_orm.Query.get` method.
:meth:`_orm.Session.get` is special in that it provides direct
access to the identity map of the :class:`.Session`.
diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py
index 03456e572..6f85508f3 100644
--- a/lib/sqlalchemy/orm/unitofwork.py
+++ b/lib/sqlalchemy/orm/unitofwork.py
@@ -21,18 +21,6 @@ from .. import util
from ..util import topological
-def _warn_for_cascade_backrefs(state, prop):
- util.warn_deprecated_20(
- '"%s" object is being merged into a Session along the backref '
- 'cascade path for relationship "%s"; in SQLAlchemy 2.0, this '
- "reverse cascade will not take place. Set cascade_backrefs to "
- "False in either the relationship() or backref() function for "
- "the 2.0 behavior; or to set globally for the whole "
- "Session, set the future=True flag" % (state.class_.__name__, prop),
- code="s9r1",
- )
-
-
def track_cascade_events(descriptor, prop):
"""Establish event listeners on object attributes which handle
cascade-on-set/append.
@@ -57,14 +45,9 @@ def track_cascade_events(descriptor, prop):
if (
prop._cascade.save_update
- and (
- (prop.cascade_backrefs and not sess.future)
- or key == initiator.key
- )
+ and (key == initiator.key)
and not sess._contains_state(item_state)
):
- if key != initiator.key:
- _warn_for_cascade_backrefs(item_state, prop)
sess._save_or_update_state(item_state)
return item
@@ -119,14 +102,9 @@ def track_cascade_events(descriptor, prop):
newvalue_state = attributes.instance_state(newvalue)
if (
prop._cascade.save_update
- and (
- (prop.cascade_backrefs and not sess.future)
- or key == initiator.key
- )
+ and (key == initiator.key)
and not sess._contains_state(newvalue_state)
):
- if key != initiator.key:
- _warn_for_cascade_backrefs(newvalue_state, prop)
sess._save_or_update_state(newvalue_state)
if (
diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py
index a282adea4..739d8a4c2 100644
--- a/lib/sqlalchemy/orm/util.py
+++ b/lib/sqlalchemy/orm/util.py
@@ -2046,25 +2046,17 @@ def randomize_unitofwork():
) = session.set = mapper.set = dependency.set = RandomSet
-def _getitem(iterable_query, item, allow_negative):
+def _getitem(iterable_query, item):
"""calculate __getitem__ in terms of an iterable query object
that also has a slice() method.
"""
def _no_negative_indexes():
- if not allow_negative:
- raise IndexError(
- "negative indexes are not accepted by SQL "
- "index / slice operators"
- )
- else:
- util.warn_deprecated_20(
- "Support for negative indexes for SQL index / slice operators "
- "will be "
- "removed in 2.0; these operators fetch the complete result "
- "and do not work efficiently."
- )
+ raise IndexError(
+ "negative indexes are not accepted by SQL "
+ "index / slice operators"
+ )
if isinstance(item, slice):
start, stop, step = util.decode_slice(item)
diff --git a/lib/sqlalchemy/sql/coercions.py b/lib/sqlalchemy/sql/coercions.py
index d11ab6712..fe4fc4b40 100644
--- a/lib/sqlalchemy/sql/coercions.py
+++ b/lib/sqlalchemy/sql/coercions.py
@@ -99,14 +99,15 @@ def _document_text_coercion(paramname, meth_rst, param_rst):
def _expression_collection_was_a_list(attrname, fnname, args):
if args and isinstance(args[0], (list, set, dict)) and len(args) == 1:
if isinstance(args[0], list):
- util.warn_deprecated_20(
- 'The "%s" argument to %s(), when referring to a sequence '
+ raise exc.ArgumentError(
+ f'The "{attrname}" argument to {fnname}(), when '
+ "referring to a sequence "
"of items, is now passed as a series of positional "
- "elements, rather than as a list. " % (attrname, fnname)
+ "elements, rather than as a list. "
)
return args[0]
- else:
- return args
+
+ return args
def expect(
@@ -883,15 +884,6 @@ class StatementImpl(_CoerceLiterals, RoleImpl):
original_element, resolved, argname=argname, **kw
)
- def _text_coercion(self, element, argname=None):
- util.warn_deprecated_20(
- "Using plain strings to indicate SQL statements without using "
- "the text() construct is "
- "deprecated and will be removed in version 2.0. Ensure plain "
- "SQL statements are passed using the text() construct."
- )
- return elements.TextClause(element)
-
class SelectStatementImpl(_NoTextCoercion, RoleImpl):
__slots__ = ()
diff --git a/lib/sqlalchemy/sql/dml.py b/lib/sqlalchemy/sql/dml.py
index feb286d65..fad1728f8 100644
--- a/lib/sqlalchemy/sql/dml.py
+++ b/lib/sqlalchemy/sql/dml.py
@@ -237,66 +237,6 @@ class UpdateBase(
is_dml = True
- @classmethod
- def _constructor_20_deprecations(cls, fn_name, clsname, names):
-
- param_to_method_lookup = dict(
- whereclause=(
- "The :paramref:`%(func)s.whereclause` parameter "
- "will be removed "
- "in SQLAlchemy 2.0. Please refer to the "
- ":meth:`%(classname)s.where` method."
- ),
- values=(
- "The :paramref:`%(func)s.values` parameter will be removed "
- "in SQLAlchemy 2.0. Please refer to the "
- ":meth:`%(classname)s.values` method."
- ),
- inline=(
- "The :paramref:`%(func)s.inline` parameter will be "
- "removed in "
- "SQLAlchemy 2.0. Please use the "
- ":meth:`%(classname)s.inline` method."
- ),
- prefixes=(
- "The :paramref:`%(func)s.prefixes parameter will be "
- "removed in "
- "SQLAlchemy 2.0. Please use the "
- ":meth:`%(classname)s.prefix_with` "
- "method."
- ),
- return_defaults=(
- "The :paramref:`%(func)s.return_defaults` parameter will be "
- "removed in SQLAlchemy 2.0. Please use the "
- ":meth:`%(classname)s.return_defaults` method."
- ),
- returning=(
- "The :paramref:`%(func)s.returning` parameter will be "
- "removed in SQLAlchemy 2.0. Please use the "
- ":meth:`%(classname)s.returning`` method."
- ),
- preserve_parameter_order=(
- "The :paramref:`%(func)s.preserve_parameter_order` parameter "
- "will be removed in SQLAlchemy 2.0. Use the "
- ":meth:`%(classname)s.ordered_values` method with a list "
- "of tuples. "
- ),
- )
-
- return util.deprecated_params(
- **{
- name: (
- "2.0",
- param_to_method_lookup[name]
- % {
- "func": "_expression.%s" % fn_name,
- "classname": "_expression.%s" % clsname,
- },
- )
- for name in names
- }
- )
-
def _generate_fromclause_column_proxies(self, fromclause):
fromclause._columns._populate_separate_keys(
col._make_proxy(fromclause) for col in self._returning
@@ -332,15 +272,6 @@ class UpdateBase(
self._validate_dialect_kwargs(opt)
return self
- def _validate_dialect_kwargs_deprecated(self, dialect_kw):
- util.warn_deprecated_20(
- "Passing dialect keyword arguments directly to the "
- "%s constructor is deprecated and will be removed in SQLAlchemy "
- "2.0. Please use the ``with_dialect_options()`` method."
- % (self.__class__.__name__)
- )
- self._validate_dialect_kwargs(dialect_kw)
-
@_generative
def returning(self: SelfUpdateBase, *cols) -> SelfUpdateBase:
r"""Add a :term:`RETURNING` or equivalent clause to this statement.
@@ -499,14 +430,10 @@ class ValuesBase(UpdateBase):
_returning = ()
- def __init__(self, table, values, prefixes):
+ def __init__(self, table):
self.table = coercions.expect(
roles.DMLTableRole, table, apply_propagate_attrs=self
)
- if values is not None:
- self.values.non_generative(self, values)
- if prefixes:
- self._setup_prefixes(prefixes)
@_generative
@_exclusive_against(
@@ -765,7 +692,7 @@ class ValuesBase(UpdateBase):
:meth:`.ValuesBase.return_defaults` is used by the ORM to provide
an efficient implementation for the ``eager_defaults`` feature of
- :func:`.mapper`.
+ :class:`_orm.Mapper`.
:param cols: optional list of column key names or
:class:`_schema.Column`
@@ -809,6 +736,7 @@ class Insert(ValuesBase):
select = None
include_insert_from_select_defaults = False
+ _inline = False
is_insert = True
@@ -835,26 +763,9 @@ class Insert(ValuesBase):
+ HasCTE._has_ctes_traverse_internals
)
- @ValuesBase._constructor_20_deprecations(
- "insert",
- "Insert",
- [
- "values",
- "inline",
- "prefixes",
- "returning",
- "return_defaults",
- ],
- )
def __init__(
self,
table,
- values=None,
- inline=False,
- prefixes=None,
- returning=None,
- return_defaults=False,
- **dialect_kw,
):
"""Construct an :class:`_expression.Insert` object.
@@ -922,17 +833,7 @@ class Insert(ValuesBase):
:ref:`inserts_and_updates` - SQL Expression Tutorial
"""
- super(Insert, self).__init__(table, values, prefixes)
- self._inline = inline
- if returning:
- self._returning = returning
- if dialect_kw:
- self._validate_dialect_kwargs_deprecated(dialect_kw)
-
- if return_defaults:
- self._return_defaults = True
- if not isinstance(return_defaults, bool):
- self._return_defaults_columns = return_defaults
+ super(Insert, self).__init__(table)
@_generative
def inline(self: SelfInsert) -> SelfInsert:
@@ -1120,6 +1021,8 @@ class Update(DMLWhereBase, ValuesBase):
__visit_name__ = "update"
is_update = True
+ _preserve_parameter_order = False
+ _inline = False
_traverse_internals = (
[
@@ -1142,30 +1045,9 @@ class Update(DMLWhereBase, ValuesBase):
+ HasCTE._has_ctes_traverse_internals
)
- @ValuesBase._constructor_20_deprecations(
- "update",
- "Update",
- [
- "whereclause",
- "values",
- "inline",
- "prefixes",
- "returning",
- "return_defaults",
- "preserve_parameter_order",
- ],
- )
def __init__(
self,
table,
- whereclause=None,
- values=None,
- inline=False,
- prefixes=None,
- returning=None,
- return_defaults=False,
- preserve_parameter_order=False,
- **dialect_kw,
):
r"""Construct an :class:`_expression.Update` object.
@@ -1275,18 +1157,7 @@ class Update(DMLWhereBase, ValuesBase):
"""
- self._preserve_parameter_order = preserve_parameter_order
- super(Update, self).__init__(table, values, prefixes)
- if returning:
- self._returning = returning
- if whereclause is not None:
- self._where_criteria += (
- coercions.expect(roles.WhereHavingRole, whereclause),
- )
- self._inline = inline
- if dialect_kw:
- self._validate_dialect_kwargs_deprecated(dialect_kw)
- self._return_defaults = return_defaults
+ super(Update, self).__init__(table)
@_generative
def ordered_values(self: SelfUpdate, *args) -> SelfUpdate:
@@ -1373,18 +1244,9 @@ class Delete(DMLWhereBase, UpdateBase):
+ HasCTE._has_ctes_traverse_internals
)
- @ValuesBase._constructor_20_deprecations(
- "delete",
- "Delete",
- ["whereclause", "values", "prefixes", "returning"],
- )
def __init__(
self,
table,
- whereclause=None,
- returning=None,
- prefixes=None,
- **dialect_kw,
):
r"""Construct :class:`_expression.Delete` object.
@@ -1424,16 +1286,3 @@ class Delete(DMLWhereBase, UpdateBase):
self.table = coercions.expect(
roles.DMLTableRole, table, apply_propagate_attrs=self
)
- if returning:
- self._returning = returning
-
- if prefixes:
- self._setup_prefixes(prefixes)
-
- if whereclause is not None:
- self._where_criteria += (
- coercions.expect(roles.WhereHavingRole, whereclause),
- )
-
- if dialect_kw:
- self._validate_dialect_kwargs_deprecated(dialect_kw)
diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py
index 6e5fbba88..3ec702e10 100644
--- a/lib/sqlalchemy/sql/elements.py
+++ b/lib/sqlalchemy/sql/elements.py
@@ -2785,10 +2785,7 @@ class Case(ColumnElement):
("else_", InternalTraversal.dp_clauseelement),
]
- # TODO: for Py2k removal, this will be:
- # def __init__(self, *whens, value=None, else_=None):
-
- def __init__(self, *whens, **kw):
+ def __init__(self, *whens, value=None, else_=None):
r"""Produce a ``CASE`` expression.
The ``CASE`` construct in SQL is a conditional object that
@@ -2875,8 +2872,7 @@ class Case(ColumnElement):
whether or not :paramref:`.case.value` is used.
.. versionchanged:: 1.4 the :func:`_sql.case`
- function now accepts the series of WHEN conditions positionally;
- passing the expressions within a list is deprecated.
+ function now accepts the series of WHEN conditions positionally
In the first form, it accepts a list of 2-tuples; each 2-tuple
consists of ``(<sql expression>, <value>)``, where the SQL
@@ -2911,24 +2907,14 @@ class Case(ColumnElement):
"""
- if "whens" in kw:
- util.warn_deprecated_20(
- 'The "whens" argument to case() is now passed using '
- "positional style only, not as a keyword argument."
- )
- whens = (kw.pop("whens"),)
-
whens = coercions._expression_collection_was_a_list(
"whens", "case", whens
)
-
try:
whens = util.dictlike_iteritems(whens)
except TypeError:
pass
- value = kw.pop("value", None)
-
whenlist = [
(
coercions.expect(
@@ -2954,15 +2940,11 @@ class Case(ColumnElement):
self.type = type_
self.whens = whenlist
- else_ = kw.pop("else_", None)
if else_ is not None:
self.else_ = coercions.expect(roles.ExpressionElementRole, else_)
else:
self.else_ = None
- if kw:
- raise TypeError("unknown arguments: %s" % (", ".join(sorted(kw))))
-
@property
def _from_objects(self):
return list(
diff --git a/lib/sqlalchemy/sql/schema.py b/lib/sqlalchemy/sql/schema.py
index a5fdd39d4..d836384b4 100644
--- a/lib/sqlalchemy/sql/schema.py
+++ b/lib/sqlalchemy/sql/schema.py
@@ -538,12 +538,6 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
"1.4",
"Deprecated alias of :paramref:`_schema.Table.must_exist`",
),
- autoload=(
- "2.0",
- "The autoload parameter is deprecated and will be removed in "
- "version 2.0. Please use the "
- "autoload_with parameter, passing an engine or connection.",
- ),
)
def __new__(cls, *args, **kw):
if not args and not kw:
@@ -638,7 +632,7 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
self.fullname = self.name
autoload_with = kwargs.pop("autoload_with", None)
- autoload = kwargs.pop("autoload", autoload_with is not None)
+ autoload = autoload_with is not None
# this argument is only used with _init_existing()
kwargs.pop("autoload_replace", True)
keep_existing = kwargs.pop("keep_existing", False)
diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py
index 9c5850761..046b41d89 100644
--- a/lib/sqlalchemy/sql/selectable.py
+++ b/lib/sqlalchemy/sql/selectable.py
@@ -1360,110 +1360,6 @@ class Join(roles.DMLTableRole, FromClause):
.alias(name)
)
- @util.deprecated_20(
- ":meth:`_sql.Join.alias`",
- alternative="Create a select + subquery, or alias the "
- "individual tables inside the join, instead.",
- )
- def alias(self, name=None, flat=False):
- r"""Return an alias of this :class:`_expression.Join`.
-
- The default behavior here is to first produce a SELECT
- construct from this :class:`_expression.Join`, then to produce an
- :class:`_expression.Alias` from that. So given a join of the form::
-
- j = table_a.join(table_b, table_a.c.id == table_b.c.a_id)
-
- The JOIN by itself would look like::
-
- table_a JOIN table_b ON table_a.id = table_b.a_id
-
- Whereas the alias of the above, ``j.alias()``, would in a
- SELECT context look like::
-
- (SELECT table_a.id AS table_a_id, table_b.id AS table_b_id,
- table_b.a_id AS table_b_a_id
- FROM table_a
- JOIN table_b ON table_a.id = table_b.a_id) AS anon_1
-
- The equivalent long-hand form, given a :class:`_expression.Join`
- object ``j``, is::
-
- from sqlalchemy import select, alias
- j = alias(
- select(j.left, j.right).\
- select_from(j).\
- set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL).\
- correlate(False),
- name=name
- )
-
- The selectable produced by :meth:`_expression.Join.alias`
- features the same
- columns as that of the two individual selectables presented under
- a single name - the individual columns are "auto-labeled", meaning
- the ``.c.`` collection of the resulting :class:`_expression.Alias`
- represents
- the names of the individual columns using a
- ``<tablename>_<columname>`` scheme::
-
- j.c.table_a_id
- j.c.table_b_a_id
-
- :meth:`_expression.Join.alias` also features an alternate
- option for aliasing joins which produces no enclosing SELECT and
- does not normally apply labels to the column names. The
- ``flat=True`` option will call :meth:`_expression.FromClause.alias`
- against the left and right sides individually.
- Using this option, no new ``SELECT`` is produced;
- we instead, from a construct as below::
-
- j = table_a.join(table_b, table_a.c.id == table_b.c.a_id)
- j = j.alias(flat=True)
-
- we get a result like this::
-
- table_a AS table_a_1 JOIN table_b AS table_b_1 ON
- table_a_1.id = table_b_1.a_id
-
- The ``flat=True`` argument is also propagated to the contained
- selectables, so that a composite join such as::
-
- j = table_a.join(
- table_b.join(table_c,
- table_b.c.id == table_c.c.b_id),
- table_b.c.a_id == table_a.c.id
- ).alias(flat=True)
-
- Will produce an expression like::
-
- table_a AS table_a_1 JOIN (
- table_b AS table_b_1 JOIN table_c AS table_c_1
- ON table_b_1.id = table_c_1.b_id
- ) ON table_a_1.id = table_b_1.a_id
-
- The standalone :func:`_expression.alias` function as well as the
- base :meth:`_expression.FromClause.alias`
- method also support the ``flat=True``
- argument as a no-op, so that the argument can be passed to the
- ``alias()`` method of any selectable.
-
- :param name: name given to the alias.
-
- :param flat: if True, produce an alias of the left and right
- sides of this :class:`_expression.Join` and return the join of those
- two selectables. This produces join expression that does not
- include an enclosing SELECT.
-
- .. seealso::
-
- :ref:`core_tutorial_aliases`
-
- :func:`_expression.alias`
-
- """
- return self._anonymous_fromclause(flat=flat, name=name)
-
@property
def _hide_froms(self):
return itertools.chain(
@@ -2618,7 +2514,6 @@ class TableClause(roles.DMLTableRole, Immutable, FromClause):
.. versionadded:: 1.3.18 :func:`_expression.table` can now
accept a ``schema`` argument.
"""
-
super(TableClause, self).__init__()
self.name = name
self._columns = DedupeColumnCollection()
@@ -2665,7 +2560,7 @@ class TableClause(roles.DMLTableRole, Immutable, FromClause):
c.table = self
@util.preload_module("sqlalchemy.sql.dml")
- def insert(self, values=None, inline=False, **kwargs):
+ def insert(self):
"""Generate an :func:`_expression.insert` construct against this
:class:`_expression.TableClause`.
@@ -2676,12 +2571,10 @@ class TableClause(roles.DMLTableRole, Immutable, FromClause):
See :func:`_expression.insert` for argument and usage information.
"""
- return util.preloaded.sql_dml.Insert(
- self, values=values, inline=inline, **kwargs
- )
+ return util.preloaded.sql_dml.Insert(self)
@util.preload_module("sqlalchemy.sql.dml")
- def update(self, whereclause=None, values=None, inline=False, **kwargs):
+ def update(self):
"""Generate an :func:`_expression.update` construct against this
:class:`_expression.TableClause`.
@@ -2694,14 +2587,10 @@ class TableClause(roles.DMLTableRole, Immutable, FromClause):
"""
return util.preloaded.sql_dml.Update(
self,
- whereclause=whereclause,
- values=values,
- inline=inline,
- **kwargs,
)
@util.preload_module("sqlalchemy.sql.dml")
- def delete(self, whereclause=None, **kwargs):
+ def delete(self):
"""Generate a :func:`_expression.delete` construct against this
:class:`_expression.TableClause`.
@@ -2712,7 +2601,7 @@ class TableClause(roles.DMLTableRole, Immutable, FromClause):
See :func:`_expression.delete` for argument and usage information.
"""
- return util.preloaded.sql_dml.Delete(self, whereclause, **kwargs)
+ return util.preloaded.sql_dml.Delete(self)
@property
def _from_objects(self):
@@ -2806,7 +2695,7 @@ class Values(Generative, FromClause):
("literal_binds", InternalTraversal.dp_boolean),
]
- def __init__(self, *columns, **kw):
+ def __init__(self, *columns, name=None, literal_binds=False):
r"""Construct a :class:`_expression.Values` construct.
The column expressions and the actual data for
@@ -2844,8 +2733,8 @@ class Values(Generative, FromClause):
super(Values, self).__init__()
self._column_args = columns
- self.name = kw.pop("name", None)
- self.literal_binds = kw.pop("literal_binds", False)
+ self.name = name
+ self.literal_binds = literal_binds
self.named_with_column = self.name is not None
@property
@@ -3286,65 +3175,12 @@ class SelectStatementGrouping(GroupedElement, SelectBase):
return self.element._from_objects
-class DeprecatedSelectBaseGenerations:
- """A collection of methods available on :class:`_sql.Select` and
- :class:`_sql.CompoundSelect`, these are all **deprecated** methods as they
- modify the object in-place.
-
- """
-
- @util.deprecated(
- "1.4",
- "The :meth:`_expression.GenerativeSelect.append_order_by` "
- "method is deprecated "
- "and will be removed in a future release. Use the generative method "
- ":meth:`_expression.GenerativeSelect.order_by`.",
- )
- def append_order_by(self, *clauses):
- """Append the given ORDER BY criterion applied to this selectable.
-
- The criterion will be appended to any pre-existing ORDER BY criterion.
-
- This is an **in-place** mutation method; the
- :meth:`_expression.GenerativeSelect.order_by` method is preferred,
- as it
- provides standard :term:`method chaining`.
-
- .. seealso::
-
- :meth:`_expression.GenerativeSelect.order_by`
-
- """
- self.order_by.non_generative(self, *clauses)
-
- @util.deprecated(
- "1.4",
- "The :meth:`_expression.GenerativeSelect.append_group_by` "
- "method is deprecated "
- "and will be removed in a future release. Use the generative method "
- ":meth:`_expression.GenerativeSelect.group_by`.",
- )
- def append_group_by(self, *clauses):
- """Append the given GROUP BY criterion applied to this selectable.
-
- The criterion will be appended to any pre-existing GROUP BY criterion.
-
- This is an **in-place** mutation method; the
- :meth:`_expression.GenerativeSelect.group_by` method is preferred,
- as it
- provides standard :term:`method chaining`.
-
-
- """
- self.group_by.non_generative(self, *clauses)
-
-
SelfGenerativeSelect = typing.TypeVar(
"SelfGenerativeSelect", bound="GenerativeSelect"
)
-class GenerativeSelect(DeprecatedSelectBaseGenerations, SelectBase):
+class GenerativeSelect(SelectBase):
"""Base class for SELECT statements where additional elements can be
added.
@@ -3368,39 +3204,9 @@ class GenerativeSelect(DeprecatedSelectBaseGenerations, SelectBase):
_fetch_clause_options = None
_for_update_arg = None
- def __init__(
- self,
- _label_style=LABEL_STYLE_DEFAULT,
- use_labels=False,
- limit=None,
- offset=None,
- order_by=None,
- group_by=None,
- ):
- if use_labels:
- if util.SQLALCHEMY_WARN_20:
- util.warn_deprecated_20(
- "The use_labels=True keyword argument to GenerativeSelect "
- "is deprecated and will be removed in version 2.0. Please "
- "use "
- "select.set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) "
- "if you need to replicate this legacy behavior.",
- stacklevel=4,
- )
- _label_style = LABEL_STYLE_TABLENAME_PLUS_COL
-
+ def __init__(self, _label_style=LABEL_STYLE_DEFAULT):
self._label_style = _label_style
- if limit is not None:
- self.limit.non_generative(self, limit)
- if offset is not None:
- self.offset.non_generative(self, offset)
-
- if order_by is not None:
- self.order_by.non_generative(self, *util.to_list(order_by))
- if group_by is not None:
- self.group_by.non_generative(self, *util.to_list(group_by))
-
@_generative
def with_for_update(
self: SelfGenerativeSelect,
@@ -3516,14 +3322,6 @@ class GenerativeSelect(DeprecatedSelectBaseGenerations, SelectBase):
self._label_style = style
return self
- @util.deprecated_20(
- ":meth:`_sql.GenerativeSelect.apply_labels`",
- alternative="Use set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) "
- "instead.",
- )
- def apply_labels(self):
- return self.set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)
-
@property
def _group_by_clause(self):
"""ClauseList access to group_by_clauses for legacy dialects"""
@@ -3894,9 +3692,9 @@ class CompoundSelect(HasCompileState, GenerativeSelect):
INTERSECT_ALL = util.symbol("INTERSECT ALL")
_is_from_container = True
+ _auto_correlate = False
- def __init__(self, keyword, *selects, **kwargs):
- self._auto_correlate = kwargs.pop("correlate", False)
+ def __init__(self, keyword, *selects):
self.keyword = keyword
self.selects = [
coercions.expect(roles.CompoundElementRole, s).self_group(
@@ -3905,17 +3703,7 @@ class CompoundSelect(HasCompileState, GenerativeSelect):
for s in selects
]
- if kwargs and util.SQLALCHEMY_WARN_20:
- util.warn_deprecated_20(
- "Set functions such as union(), union_all(), extract(), etc. "
- "in SQLAlchemy 2.0 will accept a "
- "series of SELECT statements only. "
- "Please use generative methods such as order_by() for "
- "additional modifications to this CompoundSelect.",
- stacklevel=4,
- )
-
- GenerativeSelect.__init__(self, **kwargs)
+ GenerativeSelect.__init__(self)
@classmethod
def _create_union(cls, *selects, **kwargs):
@@ -3938,7 +3726,7 @@ class CompoundSelect(HasCompileState, GenerativeSelect):
return CompoundSelect(CompoundSelect.UNION, *selects, **kwargs)
@classmethod
- def _create_union_all(cls, *selects, **kwargs):
+ def _create_union_all(cls, *selects):
r"""Return a ``UNION ALL`` of multiple selectables.
The returned object is an instance of
@@ -3950,15 +3738,11 @@ class CompoundSelect(HasCompileState, GenerativeSelect):
:param \*selects:
a list of :class:`_expression.Select` instances.
- :param \**kwargs:
- available keyword arguments are the same as those of
- :func:`select`.
-
"""
- return CompoundSelect(CompoundSelect.UNION_ALL, *selects, **kwargs)
+ return CompoundSelect(CompoundSelect.UNION_ALL, *selects)
@classmethod
- def _create_except(cls, *selects, **kwargs):
+ def _create_except(cls, *selects):
r"""Return an ``EXCEPT`` of multiple selectables.
The returned object is an instance of
@@ -3967,15 +3751,11 @@ class CompoundSelect(HasCompileState, GenerativeSelect):
:param \*selects:
a list of :class:`_expression.Select` instances.
- :param \**kwargs:
- available keyword arguments are the same as those of
- :func:`select`.
-
"""
- return CompoundSelect(CompoundSelect.EXCEPT, *selects, **kwargs)
+ return CompoundSelect(CompoundSelect.EXCEPT, *selects)
@classmethod
- def _create_except_all(cls, *selects, **kwargs):
+ def _create_except_all(cls, *selects):
r"""Return an ``EXCEPT ALL`` of multiple selectables.
The returned object is an instance of
@@ -3984,15 +3764,11 @@ class CompoundSelect(HasCompileState, GenerativeSelect):
:param \*selects:
a list of :class:`_expression.Select` instances.
- :param \**kwargs:
- available keyword arguments are the same as those of
- :func:`select`.
-
"""
- return CompoundSelect(CompoundSelect.EXCEPT_ALL, *selects, **kwargs)
+ return CompoundSelect(CompoundSelect.EXCEPT_ALL, *selects)
@classmethod
- def _create_intersect(cls, *selects, **kwargs):
+ def _create_intersect(cls, *selects):
r"""Return an ``INTERSECT`` of multiple selectables.
The returned object is an instance of
@@ -4001,15 +3777,11 @@ class CompoundSelect(HasCompileState, GenerativeSelect):
:param \*selects:
a list of :class:`_expression.Select` instances.
- :param \**kwargs:
- available keyword arguments are the same as those of
- :func:`select`.
-
"""
- return CompoundSelect(CompoundSelect.INTERSECT, *selects, **kwargs)
+ return CompoundSelect(CompoundSelect.INTERSECT, *selects)
@classmethod
- def _create_intersect_all(cls, *selects, **kwargs):
+ def _create_intersect_all(cls, *selects):
r"""Return an ``INTERSECT ALL`` of multiple selectables.
The returned object is an instance of
@@ -4018,12 +3790,9 @@ class CompoundSelect(HasCompileState, GenerativeSelect):
:param \*selects:
a list of :class:`_expression.Select` instances.
- :param \**kwargs:
- available keyword arguments are the same as those of
- :func:`select`.
"""
- return CompoundSelect(CompoundSelect.INTERSECT_ALL, *selects, **kwargs)
+ return CompoundSelect(CompoundSelect.INTERSECT_ALL, *selects)
def _scalar_type(self):
return self.selects[0]._scalar_type()
@@ -4117,134 +3886,6 @@ class CompoundSelect(HasCompileState, GenerativeSelect):
return self.selects[0].selected_columns
-class DeprecatedSelectGenerations:
- """A collection of methods available on :class:`_sql.Select`, these
- are all **deprecated** methods as they modify the :class:`_sql.Select`
- object in -place.
-
- """
-
- @util.deprecated(
- "1.4",
- "The :meth:`_expression.Select.append_correlation` "
- "method is deprecated "
- "and will be removed in a future release. Use the generative "
- "method :meth:`_expression.Select.correlate`.",
- )
- def append_correlation(self, fromclause):
- """Append the given correlation expression to this select()
- construct.
-
- This is an **in-place** mutation method; the
- :meth:`_expression.Select.correlate` method is preferred,
- as it provides
- standard :term:`method chaining`.
-
- """
-
- self.correlate.non_generative(self, fromclause)
-
- @util.deprecated(
- "1.4",
- "The :meth:`_expression.Select.append_column` method is deprecated "
- "and will be removed in a future release. Use the generative "
- "method :meth:`_expression.Select.add_columns`.",
- )
- def append_column(self, column):
- """Append the given column expression to the columns clause of this
- select() construct.
-
- E.g.::
-
- my_select.append_column(some_table.c.new_column)
-
- This is an **in-place** mutation method; the
- :meth:`_expression.Select.add_columns` method is preferred,
- as it provides standard
- :term:`method chaining`.
-
- """
- self.add_columns.non_generative(self, column)
-
- @util.deprecated(
- "1.4",
- "The :meth:`_expression.Select.append_prefix` method is deprecated "
- "and will be removed in a future release. Use the generative "
- "method :meth:`_expression.Select.prefix_with`.",
- )
- def append_prefix(self, clause):
- """Append the given columns clause prefix expression to this select()
- construct.
-
- This is an **in-place** mutation method; the
- :meth:`_expression.Select.prefix_with` method is preferred,
- as it provides
- standard :term:`method chaining`.
-
- """
- self.prefix_with.non_generative(self, clause)
-
- @util.deprecated(
- "1.4",
- "The :meth:`_expression.Select.append_whereclause` "
- "method is deprecated "
- "and will be removed in a future release. Use the generative "
- "method :meth:`_expression.Select.where`.",
- )
- def append_whereclause(self, whereclause):
- """Append the given expression to this select() construct's WHERE
- criterion.
-
- The expression will be joined to existing WHERE criterion via AND.
-
- This is an **in-place** mutation method; the
- :meth:`_expression.Select.where` method is preferred,
- as it provides standard
- :term:`method chaining`.
-
- """
- self.where.non_generative(self, whereclause)
-
- @util.deprecated(
- "1.4",
- "The :meth:`_expression.Select.append_having` method is deprecated "
- "and will be removed in a future release. Use the generative "
- "method :meth:`_expression.Select.having`.",
- )
- def append_having(self, having):
- """Append the given expression to this select() construct's HAVING
- criterion.
-
- The expression will be joined to existing HAVING criterion via AND.
-
- This is an **in-place** mutation method; the
- :meth:`_expression.Select.having` method is preferred,
- as it provides standard
- :term:`method chaining`.
-
- """
-
- self.having.non_generative(self, having)
-
- @util.deprecated(
- "1.4",
- "The :meth:`_expression.Select.append_from` method is deprecated "
- "and will be removed in a future release. Use the generative "
- "method :meth:`_expression.Select.select_from`.",
- )
- def append_from(self, fromclause):
- """Append the given :class:`_expression.FromClause` expression
- to this select() construct's FROM clause.
-
- This is an **in-place** mutation method; the
- :meth:`_expression.Select.select_from` method is preferred,
- as it provides
- standard :term:`method chaining`.
-
- """
- self.select_from.non_generative(self, fromclause)
-
-
@CompileState.plugin_for("default", "select")
class SelectState(util.MemoizedSlots, CompileState):
__slots__ = (
@@ -4700,7 +4341,6 @@ class Select(
HasSuffixes,
HasHints,
HasCompileState,
- DeprecatedSelectGenerations,
_SelectFromElements,
GenerativeSelect,
):
@@ -5345,7 +4985,9 @@ class Select(
)
@_generative
- def with_only_columns(self: SelfSelect, *columns, **kw) -> SelfSelect:
+ def with_only_columns(
+ self: SelfSelect, *columns, maintain_column_froms=False
+ ) -> SelfSelect:
r"""Return a new :func:`_expression.select` construct with its columns
clause replaced with the given columns.
@@ -5404,10 +5046,6 @@ class Select(
# is the case for now.
self._assert_no_memoizations()
- maintain_column_froms = kw.pop("maintain_column_froms", False)
- if kw:
- raise TypeError("unknown parameters: %s" % (", ".join(kw),))
-
if maintain_column_froms:
self.select_from.non_generative(self, *self.columns_clause_froms)
diff --git a/lib/sqlalchemy/sql/sqltypes.py b/lib/sqlalchemy/sql/sqltypes.py
index cb44fc086..3c1632172 100644
--- a/lib/sqlalchemy/sql/sqltypes.py
+++ b/lib/sqlalchemy/sql/sqltypes.py
@@ -1207,14 +1207,9 @@ class Enum(Emulated, String, SchemaType):
.. versionadded:: 1.3.8
:param omit_aliases: A boolean that when true will remove aliases from
- pep 435 enums. For backward compatibility it defaults to ``False``.
- A deprecation warning is raised if the enum has aliases and this
- flag was not set.
+ pep 435 enums. defaults to ``True``.
- .. versionadded:: 1.4.5
-
- .. deprecated:: 1.4 The default will be changed to ``True`` in
- SQLAlchemy 2.0.
+ .. versionchanged:: 2.0 This parameter now defaults to True.
"""
self._enum_init(enums, kw)
@@ -1239,7 +1234,7 @@ class Enum(Emulated, String, SchemaType):
self.values_callable = kw.pop("values_callable", None)
self._sort_key_function = kw.pop("sort_key_function", NO_ARG)
length_arg = kw.pop("length", NO_ARG)
- self._omit_aliases = kw.pop("omit_aliases", NO_ARG)
+ self._omit_aliases = kw.pop("omit_aliases", True)
values, objects = self._parse_into_values(enums, kw)
self._setup_for_values(values, objects, kw)
@@ -1284,14 +1279,6 @@ class Enum(Emulated, String, SchemaType):
_members = self.enum_class.__members__
- aliases = [n for n, v in _members.items() if v.name != n]
- if self._omit_aliases is NO_ARG and aliases:
- util.warn_deprecated_20(
- "The provided enum %s contains the aliases %s. The "
- "``omit_aliases`` will default to ``True`` in SQLAlchemy "
- "2.0. Specify a value to silence this warning."
- % (self.enum_class.__name__, aliases)
- )
if self._omit_aliases is True:
# remove aliases
members = OrderedDict(
diff --git a/lib/sqlalchemy/testing/assertions.py b/lib/sqlalchemy/testing/assertions.py
index 795b53804..978e6764f 100644
--- a/lib/sqlalchemy/testing/assertions.py
+++ b/lib/sqlalchemy/testing/assertions.py
@@ -31,7 +31,7 @@ from ..util import decorator
def expect_warnings(*messages, **kw):
"""Context manager which expects one or more warnings.
- With no arguments, squelches all SAWarning and RemovedIn20Warning emitted via
+ With no arguments, squelches all SAWarning emitted via
sqlalchemy.util.warn and sqlalchemy.util.warn_limited. Otherwise
pass string expressions that will match selected warnings via regex;
all non-matching warnings are sent through.
@@ -41,9 +41,7 @@ def expect_warnings(*messages, **kw):
Note that the test suite sets SAWarning warnings to raise exceptions.
""" # noqa
- return _expect_warnings(
- (sa_exc.RemovedIn20Warning, sa_exc.SAWarning), messages, **kw
- )
+ return _expect_warnings(sa_exc.SAWarning, messages, **kw)
@contextlib.contextmanager
@@ -199,9 +197,7 @@ def _expect_warnings(
else:
real_warn(msg, *arg, **kw)
- with mock.patch("warnings.warn", our_warn), mock.patch(
- "sqlalchemy.util.SQLALCHEMY_WARN_20", True
- ), mock.patch("sqlalchemy.util.deprecations.SQLALCHEMY_WARN_20", True):
+ with mock.patch("warnings.warn", our_warn):
try:
yield
finally:
diff --git a/lib/sqlalchemy/testing/profiling.py b/lib/sqlalchemy/testing/profiling.py
index 2761d4987..6ccfe4ea7 100644
--- a/lib/sqlalchemy/testing/profiling.py
+++ b/lib/sqlalchemy/testing/profiling.py
@@ -238,21 +238,18 @@ def function_call_count(variance=0.05, times=1, warmup=0):
# likely due to the introduction of __signature__.
from sqlalchemy.util import decorator
- from sqlalchemy.util import deprecations
- from sqlalchemy.testing import mock
@decorator
def wrap(fn, *args, **kw):
- with mock.patch.object(deprecations, "SQLALCHEMY_WARN_20", False):
- for warm in range(warmup):
- fn(*args, **kw)
+ for warm in range(warmup):
+ fn(*args, **kw)
- timerange = range(times)
- with count_functions(variance=variance):
- for time in timerange:
- rv = fn(*args, **kw)
- return rv
+ timerange = range(times)
+ with count_functions(variance=variance):
+ for time in timerange:
+ rv = fn(*args, **kw)
+ return rv
return wrap
diff --git a/lib/sqlalchemy/testing/warnings.py b/lib/sqlalchemy/testing/warnings.py
index c8e481a90..0c550731c 100644
--- a/lib/sqlalchemy/testing/warnings.py
+++ b/lib/sqlalchemy/testing/warnings.py
@@ -46,13 +46,6 @@ def setup_filters():
message="The loop argument is deprecated",
)
- # ignore things that are deprecated *as of* 2.0 :)
- warnings.filterwarnings(
- "ignore",
- category=sa_exc.SADeprecationWarning,
- message=r".*\(deprecated since: 2.0\)$",
- )
-
try:
import pytest
except ImportError:
diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py
index b452a1fda..eb9ddb313 100644
--- a/lib/sqlalchemy/util/__init__.py
+++ b/lib/sqlalchemy/util/__init__.py
@@ -70,16 +70,13 @@ from .concurrency import await_fallback
from .concurrency import await_only
from .concurrency import greenlet_spawn
from .concurrency import is_exit_exception
+from .deprecations import became_legacy_20
from .deprecations import deprecated
-from .deprecations import deprecated_20
-from .deprecations import deprecated_20_cls
from .deprecations import deprecated_cls
from .deprecations import deprecated_params
from .deprecations import inject_docstring_text
from .deprecations import moved_20
-from .deprecations import SQLALCHEMY_WARN_20
from .deprecations import warn_deprecated
-from .deprecations import warn_deprecated_20
from .langhelpers import add_parameter_text
from .langhelpers import as_interface
from .langhelpers import asbool
diff --git a/lib/sqlalchemy/util/deprecations.py b/lib/sqlalchemy/util/deprecations.py
index 4d3e04fde..6a0fdecb5 100644
--- a/lib/sqlalchemy/util/deprecations.py
+++ b/lib/sqlalchemy/util/deprecations.py
@@ -8,7 +8,6 @@
"""Helpers related to deprecation of functions, methods, classes, other
functionality."""
-import os
import re
from . import compat
@@ -20,19 +19,7 @@ from .langhelpers import inject_param_text
from .. import exc
-SQLALCHEMY_WARN_20 = False
-
-if os.getenv("SQLALCHEMY_WARN_20", "false").lower() in ("true", "yes", "1"):
- SQLALCHEMY_WARN_20 = True
-
-
def _warn_with_version(msg, version, type_, stacklevel, code=None):
- if (
- issubclass(type_, exc.Base20DeprecationWarning)
- and not SQLALCHEMY_WARN_20
- ):
- return
-
warn = type_(msg, code=code)
warn.deprecated_since = version
@@ -57,17 +44,6 @@ def warn_deprecated_limited(msg, args, version, stacklevel=3, code=None):
)
-def warn_deprecated_20(msg, stacklevel=3, code=None):
-
- _warn_with_version(
- msg,
- exc.RemovedIn20Warning.deprecated_since,
- exc.RemovedIn20Warning,
- stacklevel,
- code=code,
- )
-
-
def deprecated_cls(version, message, constructor="__init__"):
header = ".. deprecated:: %s %s" % (version, (message or ""))
@@ -84,41 +60,6 @@ def deprecated_cls(version, message, constructor="__init__"):
return decorate
-def deprecated_20_cls(
- clsname, alternative=None, constructor="__init__", becomes_legacy=False
-):
- message = (
- ".. deprecated:: 1.4 The %s class is considered legacy as of the "
- "1.x series of SQLAlchemy and %s in 2.0."
- % (
- clsname,
- "will be removed"
- if not becomes_legacy
- else "becomes a legacy construct",
- )
- )
-
- if alternative:
- message += " " + alternative
-
- if becomes_legacy:
- warning_cls = exc.LegacyAPIWarning
- else:
- warning_cls = exc.RemovedIn20Warning
-
- def decorate(cls):
- return _decorate_cls_with_warning(
- cls,
- constructor,
- warning_cls,
- message,
- warning_cls.deprecated_since,
- message,
- )
-
- return decorate
-
-
def deprecated(
version,
message=None,
@@ -142,14 +83,6 @@ def deprecated(
"""
- # nothing is deprecated "since" 2.0 at this time. All "removed in 2.0"
- # should emit the RemovedIn20Warning, but messaging should be expressed
- # in terms of "deprecated since 1.4".
-
- if version == "2.0":
- if warning is None:
- warning = exc.RemovedIn20Warning
- version = "1.4"
if add_deprecation_to_docstring:
header = ".. deprecated:: %s %s" % (
version,
@@ -164,8 +97,7 @@ def deprecated(
if warning is None:
warning = exc.SADeprecationWarning
- if warning is not exc.RemovedIn20Warning:
- message += " (deprecated since: %s)" % version
+ message += " (deprecated since: %s)" % version
def decorate(fn):
return _decorate_with_warning(
@@ -186,7 +118,7 @@ def moved_20(message, **kw):
)
-def deprecated_20(api_name, alternative=None, becomes_legacy=False, **kw):
+def became_legacy_20(api_name, alternative=None, **kw):
type_reg = re.match("^:(attr|func|meth):", api_name)
if type_reg:
type_ = {"attr": "attribute", "func": "function", "meth": "method"}[
@@ -200,9 +132,7 @@ def deprecated_20(api_name, alternative=None, becomes_legacy=False, **kw):
% (
api_name,
type_,
- "will be removed"
- if not becomes_legacy
- else "becomes a legacy construct",
+ "becomes a legacy construct",
)
)
@@ -219,10 +149,7 @@ def deprecated_20(api_name, alternative=None, becomes_legacy=False, **kw):
if alternative:
message += " " + alternative
- if becomes_legacy:
- warning_cls = exc.LegacyAPIWarning
- else:
- warning_cls = exc.RemovedIn20Warning
+ warning_cls = exc.LegacyAPIWarning
return deprecated("2.0", message=message, warning=warning_cls, **kw)
@@ -250,11 +177,7 @@ def deprecated_params(**specs):
for param, (version, message) in specs.items():
versions[param] = version
messages[param] = _sanitize_restructured_text(message)
- version_warnings[param] = (
- exc.RemovedIn20Warning
- if version == "2.0"
- else exc.SADeprecationWarning
- )
+ version_warnings[param] = exc.SADeprecationWarning
def decorate(fn):
spec = compat.inspect_getfullargspec(fn)