diff options
23 files changed, 5 insertions, 235 deletions
diff --git a/doc/build/changelog/whatsnew_20.rst b/doc/build/changelog/whatsnew_20.rst index 524b40a87..1a4519f52 100644 --- a/doc/build/changelog/whatsnew_20.rst +++ b/doc/build/changelog/whatsnew_20.rst @@ -929,7 +929,7 @@ Operations that are improved by this feature include: which improves upon the experimental version of this feature first introduced in SQLAlchemy 1.4. * the :class:`_orm.Session` "bulk" operations described at - :ref:`bulk_operations`, which are superseded by the above mentioned + bulk_operations, which are superseded by the above mentioned ORM Bulk Insert feature. To get a sense of the scale of the operation, below are performance diff --git a/doc/build/conf.py b/doc/build/conf.py index 8b1ec5efa..4485a34ac 100644 --- a/doc/build/conf.py +++ b/doc/build/conf.py @@ -35,12 +35,10 @@ needs_sphinx = "5.0.1" extensions = [ "sphinx.ext.autodoc", - "zzzeeksphinx", "changelog", "sphinx_paramlinks", "sphinx_copybutton", ] -needs_extensions = {"zzzeeksphinx": "1.2.1"} # Add any paths that contain templates here, relative to this directory. # not sure why abspath() is needed here, some users @@ -293,7 +291,7 @@ gettext_compact = False # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = "zzzeeksphinx" +html_theme = "nature" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -342,7 +340,7 @@ html_last_updated_fmt = "%m/%d/%Y %H:%M:%S" # Additional templates that should be rendered to pages, maps page names to # template names. -html_additional_pages = {"notfound": "notfound.html"} +# html_additional_pages = {"notfound": "notfound.html"} # If false, no module index is generated. html_domain_indices = False diff --git a/doc/build/core/connections.rst b/doc/build/core/connections.rst index abb6d6c4c..b47a0a949 100644 --- a/doc/build/core/connections.rst +++ b/doc/build/core/connections.rst @@ -1351,12 +1351,6 @@ SELECTs with LIMIT/OFFSET are correctly rendered and cached. Using Lambdas to add significant speed gains to statement production ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. deepalchemy:: This technique is generally non-essential except in very performance - intensive scenarios, and intended for experienced Python programmers. - While fairly straightforward, it involves metaprogramming concepts that are - not appropriate for novice Python developers. The lambda approach can be - applied to at a later time to existing code with a minimal amount of effort. - Python functions, typically expressed as lambdas, may be used to generate SQL expressions which are cacheable based on the Python code location of the lambda function itself as well as the closure variables within the diff --git a/doc/build/orm/internals.rst b/doc/build/orm/internals.rst index 529baf1d1..a6ffa663f 100644 --- a/doc/build/orm/internals.rst +++ b/doc/build/orm/internals.rst @@ -22,9 +22,6 @@ sections, are listed here. .. autoclass:: Composite -.. .. autoclass:: CompositeProperty - .. :members: - .. autoclass:: AttributeEventToken :members: diff --git a/doc/build/orm/persistence_techniques.rst b/doc/build/orm/persistence_techniques.rst index d28965bf9..61bdbcbab 100644 --- a/doc/build/orm/persistence_techniques.rst +++ b/doc/build/orm/persistence_techniques.rst @@ -831,14 +831,3 @@ ORM extension. An example of use is at: ref_examples_sharding. .. _bulk_operations: -Bulk Operations -=============== - -.. legacy:: - - SQLAlchemy 2.0 has integrated the :class:`_orm.Session` "bulk insert" and - "bulk update" capabilities into 2.0 style :meth:`_orm.Session.execute` - method, making direct use of :class:`_dml.Insert` and :class:`_dml.Update` - constructs. See the document at :doc:`queryguide/dml` for documentation, - including :ref:`orm_queryguide_legacy_bulk_insert` which illustrates migration - from the older methods to the new methods. diff --git a/doc/build/orm/queryguide/api.rst b/doc/build/orm/queryguide/api.rst index a5b155447..38e5a3a79 100644 --- a/doc/build/orm/queryguide/api.rst +++ b/doc/build/orm/queryguide/api.rst @@ -287,12 +287,6 @@ Identity Token .. doctest-disable: -.. deepalchemy:: This option is an advanced-use feature mostly intended - to be used with the ref_horizontal_sharding_toplevel extension. For - typical cases of loading objects with identical primary keys from different - "shards" or partitions, consider using individual :class:`_orm.Session` - objects per shard first. - The "identity token" is an arbitrary value that can be associated within the :term:`identity key` of newly loaded objects. This element exists diff --git a/doc/build/orm/queryguide/queryguide_nav_include.rst b/doc/build/orm/queryguide/queryguide_nav_include.rst index a86002164..0534c3e7e 100644 --- a/doc/build/orm/queryguide/queryguide_nav_include.rst +++ b/doc/build/orm/queryguide/queryguide_nav_include.rst @@ -8,7 +8,4 @@ Previous: |prev| | Next: |next| -.. footer_topic:: |tutorial_title| - - Next Query Guide Section: |next| diff --git a/doc/build/orm/queryguide/relationships.rst b/doc/build/orm/queryguide/relationships.rst index 70f9d318c..5665264a1 100644 --- a/doc/build/orm/queryguide/relationships.rst +++ b/doc/build/orm/queryguide/relationships.rst @@ -850,18 +850,6 @@ Things to know about this kind of loading include: Subquery Eager Loading ---------------------- -.. legacy:: The :func:`_orm.subqueryload` eager loader is mostly legacy - at this point, superseded by the :func:`_orm.selectinload` strategy - which is of much simpler design, more flexible with features such as - :ref:`Yield Per <orm_queryguide_yield_per>`, and emits more efficient SQL - statements in most cases. As :func:`_orm.subqueryload` relies upon - re-interpreting the original SELECT statement, it may fail to work - efficiently when given very complex source queries. - - :func:`_orm.subqueryload` may continue to be useful for the specific - case of an eager loaded collection for objects that use composite primary - keys, on the Microsoft SQL Server backend that continues to not have - support for the "tuple IN" syntax. Subquery loading is similar in operation to selectin eager loading, however the SELECT statement which is emitted is derived from the original statement, diff --git a/doc/build/orm/session_events.rst b/doc/build/orm/session_events.rst index 584a3402e..d98be69f5 100644 --- a/doc/build/orm/session_events.rst +++ b/doc/build/orm/session_events.rst @@ -168,13 +168,6 @@ to intercept all objects that extend from ``HasTimestamp`` and filter their Re-Executing Statements ^^^^^^^^^^^^^^^^^^^^^^^ -.. deepalchemy:: the statement re-execution feature involves a slightly - intricate recursive sequence, and is intended to solve the fairly hard - problem of being able to re-route the execution of a SQL statement into - various non-SQL contexts. The twin examples of "dogpile caching" and - "horizontal sharding", linked below, should be used as a guide for when this - rather advanced feature is appropriate to be used. - The :class:`_orm.ORMExecuteState` is capable of controlling the execution of the given statement; this includes the ability to either not invoke the statement at all, allowing a pre-constructed result set retrieved from a cache to diff --git a/doc/build/requirements.txt b/doc/build/requirements.txt index 9b9bffd36..572512f42 100644 --- a/doc/build/requirements.txt +++ b/doc/build/requirements.txt @@ -1,6 +1,5 @@ git+https://github.com/sqlalchemyorg/changelog.git#egg=changelog git+https://github.com/sqlalchemyorg/sphinx-paramlinks.git#egg=sphinx-paramlinks -git+https://github.com/sqlalchemyorg/zzzeeksphinx.git#egg=zzzeeksphinx sphinx-copybutton==0.5.1 sphinx-autobuild typing-extensions diff --git a/doc/build/tutorial/data_insert.rst b/doc/build/tutorial/data_insert.rst index d0f6b236d..651455e73 100644 --- a/doc/build/tutorial/data_insert.rst +++ b/doc/build/tutorial/data_insert.rst @@ -1,4 +1,4 @@ -.. highlight:: pycon+sql + highlight:: pycon+sql .. |prev| replace:: :doc:`data` .. |next| replace:: :doc:`data_select` @@ -157,62 +157,6 @@ method in conjunction with the :class:`_sql.Insert` construct, the will be expressed in the VALUES clause of the :class:`_sql.Insert` construct automatically. -.. deepalchemy:: - - Hi, welcome to the first edition of **Deep Alchemy**. The person on the - left is known as **The Alchemist**, and you'll note they are **not** a wizard, - as the pointy hat is not sticking upwards. The Alchemist comes around to - describe things that are generally **more advanced and/or tricky** and - additionally **not usually needed**, but for whatever reason they feel you - should know about this thing that SQLAlchemy can do. - - In this edition, towards the goal of having some interesting data in the - ``address_table`` as well, below is a more advanced example illustrating - how the :meth:`_sql.Insert.values` method may be used explicitly while at - the same time including for additional VALUES generated from the - parameters. A :term:`scalar subquery` is constructed, making use of the - :func:`_sql.select` construct introduced in the next section, and the - parameters used in the subquery are set up using an explicit bound - parameter name, established using the :func:`_sql.bindparam` construct. - - This is some slightly **deeper** alchemy just so that we can add related - rows without fetching the primary key identifiers from the ``user_table`` - operation into the application. Most Alchemists will simply use the ORM - which takes care of things like this for us. - - .. sourcecode:: pycon+sql - - >>> from sqlalchemy import select, bindparam - >>> scalar_subq = ( - ... select(user_table.c.id) - ... .where(user_table.c.name == bindparam("username")) - ... .scalar_subquery() - ... ) - - >>> with engine.connect() as conn: - ... result = conn.execute( - ... insert(address_table).values(user_id=scalar_subq), - ... [ - ... { - ... "username": "spongebob", - ... "email_address": "spongebob@sqlalchemy.org", - ... }, - ... {"username": "sandy", "email_address": "sandy@sqlalchemy.org"}, - ... {"username": "sandy", "email_address": "sandy@squirrelpower.org"}, - ... ], - ... ) - ... conn.commit() - {execsql}BEGIN (implicit) - INSERT INTO address (user_id, email_address) VALUES ((SELECT user_account.id - FROM user_account - WHERE user_account.name = ?), ?) - [...] [('spongebob', 'spongebob@sqlalchemy.org'), ('sandy', 'sandy@sqlalchemy.org'), - ('sandy', 'sandy@squirrelpower.org')] - COMMIT{stop} - - With that, we have some more interesting data in our tables that we will - make use of in the upcoming sections. - .. tip:: A true "empty" INSERT that inserts only the "defaults" for a table without including any explicit values at all is generated if we indicate :meth:`_sql.Insert.values` with no arguments; not every database backend diff --git a/doc/build/tutorial/index.rst b/doc/build/tutorial/index.rst index ef4bb7634..e9477528f 100644 --- a/doc/build/tutorial/index.rst +++ b/doc/build/tutorial/index.rst @@ -1,10 +1,6 @@ .. |tutorial_title| replace:: SQLAlchemy Unified Tutorial .. |next| replace:: :doc:`engine` -.. footer_topic:: |tutorial_title| - - Next Section: |next| - .. _unified_tutorial: .. rst-class:: orm_core diff --git a/doc/build/tutorial/tutorial_nav_include.rst b/doc/build/tutorial/tutorial_nav_include.rst index c4ee772a8..a6128595a 100644 --- a/doc/build/tutorial/tutorial_nav_include.rst +++ b/doc/build/tutorial/tutorial_nav_include.rst @@ -8,7 +8,4 @@ Previous: |prev| | Next: |next| -.. footer_topic:: |tutorial_title| - - Next Tutorial Section: |next| diff --git a/lib/sqlalchemy/ext/horizontal_shard.py b/lib/sqlalchemy/ext/horizontal_shard.py index ac800917c..fa03d473c 100644 --- a/lib/sqlalchemy/ext/horizontal_shard.py +++ b/lib/sqlalchemy/ext/horizontal_shard.py @@ -102,13 +102,7 @@ class IdentityChooser(Protocol): class ShardedQuery(Query[_T]): - """Query class used with :class:`.ShardedSession`. - - .. legacy:: The :class:`.ShardedQuery` is a subclass of the legacy - :class:`.Query` class. The :class:`.ShardedSession` now supports - 2.0 style execution via the :meth:`.ShardedSession.execute` method. - - """ + """Query class used with :class:`.ShardedSession`.""" def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) diff --git a/lib/sqlalchemy/ext/serializer.py b/lib/sqlalchemy/ext/serializer.py index 706bff29f..159054254 100644 --- a/lib/sqlalchemy/ext/serializer.py +++ b/lib/sqlalchemy/ext/serializer.py @@ -9,10 +9,6 @@ """Serializer/Deserializer objects for usage with SQLAlchemy query structures, allowing "contextual" deserialization. -.. legacy:: - - The serializer extension is **legacy** and should not be used for - new development. Any SQLAlchemy query structure, either based on sqlalchemy.sql.* or sqlalchemy.orm.* can be used. The mappers, Tables, Columns, Session diff --git a/lib/sqlalchemy/orm/_orm_constructors.py b/lib/sqlalchemy/orm/_orm_constructors.py index 207c4410d..55876bb2b 100644 --- a/lib/sqlalchemy/orm/_orm_constructors.py +++ b/lib/sqlalchemy/orm/_orm_constructors.py @@ -1384,9 +1384,6 @@ def relationship( left hand side within a Declarative mapping. See the section ref_dynamic_relationship for examples. - .. legacy:: The "dynamic" lazy loader strategy is the legacy form of - what is now the "write_only" strategy described in the section - ref_write_only_relationship. .. seealso:: diff --git a/lib/sqlalchemy/orm/base.py b/lib/sqlalchemy/orm/base.py index 3e178d524..9d75f194e 100644 --- a/lib/sqlalchemy/orm/base.py +++ b/lib/sqlalchemy/orm/base.py @@ -883,9 +883,6 @@ class DynamicMapped(_MappedAnnotationBase[_T]): to indicate that the ``lazy="dynamic"`` loader strategy should be used for a particular :func:`_orm.relationship`. - .. legacy:: The "dynamic" lazy loader strategy is the legacy form of what - is now the "write_only" strategy described in the section - ref_write_only_relationship. E.g.:: diff --git a/lib/sqlalchemy/orm/dynamic.py b/lib/sqlalchemy/orm/dynamic.py index 7514d86cd..9a067bca2 100644 --- a/lib/sqlalchemy/orm/dynamic.py +++ b/lib/sqlalchemy/orm/dynamic.py @@ -12,8 +12,6 @@ Dynamic collections act like Query() objects for read operations and support basic add/delete mutation. -.. legacy:: the "dynamic" loader is a legacy feature, superseded by the - "write_only" loader. """ diff --git a/lib/sqlalchemy/orm/events.py b/lib/sqlalchemy/orm/events.py index 538ac8979..c23ef3ffa 100644 --- a/lib/sqlalchemy/orm/events.py +++ b/lib/sqlalchemy/orm/events.py @@ -2110,13 +2110,6 @@ class SessionEvents(event.Events[Session]): """Event for after the legacy :meth:`_orm.Query.update` method has been called. - .. legacy:: The :meth:`_orm.SessionEvents.after_bulk_update` method - is a legacy event hook as of SQLAlchemy 2.0. The event - **does not participate** in :term:`2.0 style` invocations - using :func:`_dml.update` documented at - :ref:`orm_queryguide_update_delete_where`. For 2.0 style use, - the :meth:`_orm.SessionEvents.do_orm_execute` hook will intercept - these calls. :param update_context: an "update context" object which contains details about the update, including these attributes: @@ -2156,13 +2149,6 @@ class SessionEvents(event.Events[Session]): """Event for after the legacy :meth:`_orm.Query.delete` method has been called. - .. legacy:: The :meth:`_orm.SessionEvents.after_bulk_delete` method - is a legacy event hook as of SQLAlchemy 2.0. The event - **does not participate** in :term:`2.0 style` invocations - using :func:`_dml.delete` documented at - :ref:`orm_queryguide_update_delete_where`. For 2.0 style use, - the :meth:`_orm.SessionEvents.do_orm_execute` hook will intercept - these calls. :param delete_context: a "delete context" object which contains details about the update, including these attributes: @@ -3044,11 +3030,6 @@ class QueryEvents(event.Events[Query[Any]]): """Represent events within the construction of a :class:`_query.Query` object. - .. legacy:: The :class:`_orm.QueryEvents` event methods are legacy - as of SQLAlchemy 2.0, and only apply to direct use of the - :class:`_orm.Query` object. They are not used for :term:`2.0 style` - statements. For events to intercept and modify 2.0 style ORM use, - use the :meth:`_orm.SessionEvents.do_orm_execute` hook. The :class:`_orm.QueryEvents` hooks are now superseded by the diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index dcda45bd4..c28b25d78 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -168,10 +168,6 @@ class Query( """ORM-level SQL construction object. - .. legacy:: The ORM :class:`.Query` object is a legacy construct - as of SQLAlchemy 2.0. See the notes at the top of - :ref:`query_api_toplevel` for an overview, including links to migration - documentation. :class:`_query.Query` objects are normally initially generated using the :meth:`~.Session.query` method of :class:`.Session`, and in diff --git a/lib/sqlalchemy/orm/scoping.py b/lib/sqlalchemy/orm/scoping.py index 4d1bba555..05ec0299e 100644 --- a/lib/sqlalchemy/orm/scoping.py +++ b/lib/sqlalchemy/orm/scoping.py @@ -266,9 +266,6 @@ class scoped_session(Generic[_S]): :class:`_query.Query` object against the class and the current :class:`.Session` when called. - .. legacy:: The :meth:`_orm.scoped_session.query_property` accessor - is specific to the legacy :class:`.Query` object and is not - considered to be part of :term:`2.0-style` ORM use. e.g.:: @@ -1189,19 +1186,6 @@ class scoped_session(Generic[_S]): Proxied for the :class:`_orm.Session` class on behalf of the :class:`_orm.scoping.scoped_session` class. - .. legacy:: - - This method is a legacy feature as of the 2.0 series of - SQLAlchemy. For modern bulk INSERT and UPDATE, see - the sections :ref:`orm_queryguide_bulk_insert` and - :ref:`orm_queryguide_bulk_update`. - - For general INSERT and UPDATE of existing ORM mapped objects, - prefer standard :term:`unit of work` data management patterns, - introduced in the :ref:`unified_tutorial` at - :ref:`tutorial_orm_data_manipulation`. SQLAlchemy 2.0 - now uses :ref:`engine_insertmanyvalues` with modern dialects - which solves previous issues of bulk INSERT slowness. :param objects: a sequence of mapped object instances. The mapped objects are persisted as is, and are **not** associated with the @@ -1275,14 +1259,6 @@ class scoped_session(Generic[_S]): Proxied for the :class:`_orm.Session` class on behalf of the :class:`_orm.scoping.scoped_session` class. - .. legacy:: - - This method is a legacy feature as of the 2.0 series of - SQLAlchemy. For modern bulk INSERT and UPDATE, see - the sections :ref:`orm_queryguide_bulk_insert` and - :ref:`orm_queryguide_bulk_update`. The 2.0 API shares - implementation details with this method and adds new features - as well. :param mapper: a mapped class, or the actual :class:`_orm.Mapper` object, @@ -1358,14 +1334,6 @@ class scoped_session(Generic[_S]): Proxied for the :class:`_orm.Session` class on behalf of the :class:`_orm.scoping.scoped_session` class. - .. legacy:: - - This method is a legacy feature as of the 2.0 series of - SQLAlchemy. For modern bulk INSERT and UPDATE, see - the sections :ref:`orm_queryguide_bulk_insert` and - :ref:`orm_queryguide_bulk_update`. The 2.0 API shares - implementation details with this method and adds new features - as well. :param mapper: a mapped class, or the actual :class:`_orm.Mapper` object, diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index 3b65e728a..353e4a4db 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -4298,20 +4298,6 @@ class Session(_SessionClassMethods, EventTarget): ) -> None: """Perform a bulk save of the given list of objects. - .. legacy:: - - This method is a legacy feature as of the 2.0 series of - SQLAlchemy. For modern bulk INSERT and UPDATE, see - the sections :ref:`orm_queryguide_bulk_insert` and - :ref:`orm_queryguide_bulk_update`. - - For general INSERT and UPDATE of existing ORM mapped objects, - prefer standard :term:`unit of work` data management patterns, - introduced in the :ref:`unified_tutorial` at - :ref:`tutorial_orm_data_manipulation`. SQLAlchemy 2.0 - now uses :ref:`engine_insertmanyvalues` with modern dialects - which solves previous issues of bulk INSERT slowness. - :param objects: a sequence of mapped object instances. The mapped objects are persisted as is, and are **not** associated with the :class:`.Session` afterwards. @@ -4403,15 +4389,6 @@ class Session(_SessionClassMethods, EventTarget): ) -> None: """Perform a bulk insert of the given list of mapping dictionaries. - .. legacy:: - - This method is a legacy feature as of the 2.0 series of - SQLAlchemy. For modern bulk INSERT and UPDATE, see - the sections :ref:`orm_queryguide_bulk_insert` and - :ref:`orm_queryguide_bulk_update`. The 2.0 API shares - implementation details with this method and adds new features - as well. - :param mapper: a mapped class, or the actual :class:`_orm.Mapper` object, representing the single kind of object represented within the mapping @@ -4482,14 +4459,6 @@ class Session(_SessionClassMethods, EventTarget): ) -> None: """Perform a bulk update of the given list of mapping dictionaries. - .. legacy:: - - This method is a legacy feature as of the 2.0 series of - SQLAlchemy. For modern bulk INSERT and UPDATE, see - the sections :ref:`orm_queryguide_bulk_insert` and - :ref:`orm_queryguide_bulk_update`. The 2.0 API shares - implementation details with this method and adds new features - as well. :param mapper: a mapped class, or the actual :class:`_orm.Mapper` object, diff --git a/lib/sqlalchemy/sql/dml.py b/lib/sqlalchemy/sql/dml.py index 2ea3b3b34..1a7b7f21d 100644 --- a/lib/sqlalchemy/sql/dml.py +++ b/lib/sqlalchemy/sql/dml.py @@ -461,18 +461,6 @@ class UpdateBase( of fetching server-side expressions and defaults, for supporting backends only. - .. deepalchemy:: - - The :meth:`.UpdateBase.return_defaults` method is used by the ORM - for its internal work in fetching newly generated primary key - and server default values, in particular to provide the underyling - implementation of the :paramref:`_orm.Mapper.eager_defaults` - ORM feature as well as to allow RETURNING support with bulk - ORM inserts. Its behavior is fairly idiosyncratic - and is not really intended for general use. End users should - stick with using :meth:`.UpdateBase.returning` in order to - add RETURNING clauses to their INSERT, UPDATE and DELETE - statements. Normally, a single row INSERT statement will automatically populate the :attr:`.CursorResult.inserted_primary_key` attribute when executed, |