From: Mike Bayer Date: Thu, 11 Nov 2021 20:59:33 +0000 (-0500) Subject: pass through docs for 2.0 style X-Git-Tag: rel_2_0_0b1~652 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6206f0ff74e95c9339dc0f0e26caab55e9bcda45;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git pass through docs for 2.0 style this change restores the orm/tutorial.rst and core/tutorial.rst files, hidden from the index with an update on the new tutorial. Also started noting Query is legacy, as we will have lots of docs to update for 2.0 style. Change-Id: I4f98eeaaa0fd6e03b9976320b568975fe6d06ade --- diff --git a/doc/build/core/index.rst b/doc/build/core/index.rst index 40180bef46..4c6cfc8409 100644 --- a/doc/build/core/index.rst +++ b/doc/build/core/index.rst @@ -17,3 +17,6 @@ Language provides a schema-centric usage paradigm. engines_connections api_basics future + +.. toctree:: + :hidden: diff --git a/doc/build/core/tutorial.rst b/doc/build/core/tutorial.rst new file mode 100644 index 0000000000..c9806ce62a --- /dev/null +++ b/doc/build/core/tutorial.rst @@ -0,0 +1,14 @@ +.. _sqlexpression_toplevel: + +================================= +SQL Expression Language Tutorial +================================= + +.. admonition:: We've Moved! + + This page is the previous home of the SQLAlchemy 1.x Tutorial. As of 2.0, + SQLAlchemy presents a revised way of working and an all new tutorial that + presents Core and ORM in an integrated fashion using all the latest usage + patterns. See :ref:`unified_tutorial`. + + diff --git a/doc/build/glossary.rst b/doc/build/glossary.rst index 57c0b2c90e..08a503ecb1 100644 --- a/doc/build/glossary.rst +++ b/doc/build/glossary.rst @@ -25,55 +25,6 @@ Glossary :ref:`migration_20_toplevel` - **Enabling 2.0 style usage** - - When using code from a documentation example that indicates - :term:`2.0-style`, the :class:`_engine.Engine` as well as the - :class:`_orm.Session` in use should make use of "future" mode, - via the :paramref:`_sa.create_engine.future` and - :paramref:`_orm.Session.future` flags:: - - from sqlalchemy import create_engine - from sqlalchemy.orm import sessionmaker - - - engine = create_engine("mysql+mysqldb://user:pass@host/dbname", future=True) - Session = sessionmaker(bind=engine, future=True) - - **ORM Queries in 2.0 style** - - Besides the above changes to :class:`_engine.Engine` and - :class:`_orm.Session`, probably the most major API change implied by - 1.x->2.0 is the migration from using the :class:`_orm.Query` object for - ORM SELECT statements and instead using the :func:`_sql.select` - construct in conjunction with the :meth:`_orm.Session.execute` method. - The general change looks like the following. Given a - :class:`_orm.Session` and a :class:`_orm.Query` against that - :class:`_orm.Session`:: - - list_of_users = session.query(User).join(User.addresses).all() - - The new style constructs the query separately from the - :class:`_orm.Session` using the :func:`_sql.select` construct; when - populated with ORM entities like the ``User`` class from the :ref:`ORM - Tutorial `, the resulting :class:`_sql.Select` - construct receives additional "plugin" state that allows it to work - like the :class:`_orm.Query`:: - - - from sqlalchemy import select - - # a Core select statement with ORM entities is - # now ORM-enabled at the compiler level - stmt = select(User).join(User.addresses) - - session = Session(engine) - - result = session.execute(stmt) - - # Session returns a Result that has ORM entities - list_of_users = result.scalars().all() - facade An object that serves as a front-facing interface masking more complex diff --git a/doc/build/orm/index.rst b/doc/build/orm/index.rst index ed50cc5b31..c3ab4558dc 100644 --- a/doc/build/orm/index.rst +++ b/doc/build/orm/index.rst @@ -18,3 +18,8 @@ tutorial. extending extensions/index examples + +.. toctree:: + :hidden: + + tutorial \ No newline at end of file diff --git a/doc/build/orm/loading_objects.rst b/doc/build/orm/loading_objects.rst index 956ef2f699..02e8e1daa4 100644 --- a/doc/build/orm/loading_objects.rst +++ b/doc/build/orm/loading_objects.rst @@ -7,15 +7,8 @@ an ORM context. This involves primarily statements that return instances of ORM mapped objects, but also involves calling forms that deliver individual column or groups of columns as well. -For an introduction to querying with the SQLAlchemy ORM, one of the -following tutorials should be consulted: - -* :doc:`/tutorial/index` - for :term:`2.0 style` usage - -* :doc:`/orm/tutorial` - for :term:`1.x style` usage. - -As SQLAlchemy 1.4 represents a transition from 1.x to 2.0 style, the below -sections are currently mixed as far as which style they are using. +For an introduction to querying with the SQLAlchemy ORM, start with the +:ref:`unified_tutorial`. .. toctree:: :maxdepth: 3 diff --git a/doc/build/orm/query.rst b/doc/build/orm/query.rst index d7711671cf..e024cd1afc 100644 --- a/doc/build/orm/query.rst +++ b/doc/build/orm/query.rst @@ -2,12 +2,32 @@ .. _query_api_toplevel: -========= -Query API -========= +================ +Legacy Query API +================ + +.. admonition:: About the Legacy Query API + -This section presents the API reference for the ORM :class:`_query.Query` object. For a walkthrough -of how to use this object, see :ref:`ormtutorial_toplevel`. + This page contains the Python generated documentation for the + :class:`_query.Query` construct, which for many years was the sole SQL + interface when working with the SQLAlchemy ORM. As of version 2.0, an all + new way of working is now the standard approach, where the same + :func:`_sql.select` construct that works for Core works just as well for the + ORM, providing a consistent interface for building queries. + + For any application that is built on the SQLAlchemy ORM prior to the + 2.0 API, the :class:`_query.Query` API will usually represents the vast + majority of database access code within an application, and as such the + majority of the :class:`_query.Query` API is + **not being removed from SQLAlchemy**. The :class:`_query.Query` object + behind the scenes now translates itself into a 2.0 style :func:`_sql.select` + object when the :class:`_query.Query` object is executed, so it now is + just a very thin adapter API. + + For an introduction to writing SQL for ORM objects in the 2.0 style, + start with the :ref:`unified_tutorial`. Additional reference for 2.0 style + querying is at :ref:`queryguide_toplevel`. The Query Object ================ @@ -32,23 +52,4 @@ Following is the full interface for the :class:`_query.Query` object. ORM-Specific Query Constructs ============================= -.. autofunction:: sqlalchemy.orm.aliased - -.. autoclass:: sqlalchemy.orm.util.AliasedClass - -.. autoclass:: sqlalchemy.orm.util.AliasedInsp - -.. autoclass:: sqlalchemy.orm.Bundle - :members: - -.. autoclass:: sqlalchemy.orm.Load - :members: - -.. autofunction:: sqlalchemy.orm.with_loader_criteria - -.. autofunction:: join - -.. autofunction:: outerjoin - -.. autofunction:: with_parent - +This section has moved to :ref:`queryguide_additional`. diff --git a/doc/build/orm/queryguide.rst b/doc/build/orm/queryguide.rst index a10af53ba1..a5b8813df9 100644 --- a/doc/build/orm/queryguide.rst +++ b/doc/build/orm/queryguide.rst @@ -13,6 +13,20 @@ Readers of this section should be familiar with the SQLAlchemy overview at :ref:`unified_tutorial`, and in particular most of the content here expands upon the content at :ref:`tutorial_selecting_data`. +.. admonition:: Attention legacy users + + In the SQLAlchemy 2.x series, SQL SELECT statements for the ORM are + constructed using the same :func:`_sql.select` construct as is used in + Core, which is then invoked in terms of a :class:`_orm.Session` using the + :meth:`_orm.Session.execute` method (as are the :func:`_sql.update` and + :func:`_sql.delete` constructs now used for the + :ref:`orm_expression_update_delete` feature). However, the legacy + :class:`_query.Query` object, which performs these same steps as more of an + "all-in-one" object, continues to remain available as a thin facade over + this new system, to support applications that were built on the 1.x series + without the need for wholesale replacement of all queries. For reference on + this object, see the section :ref:`query_api_toplevel`. + .. Setup code, not for display @@ -1066,7 +1080,6 @@ The ``yield_per`` execution option is equvialent to the :ref:`engine_stream_results` - ORM Update / Delete with Arbitrary WHERE clause ================================================ @@ -1081,4 +1094,31 @@ matching objects locally present in the :class:`_orm.Session`. See the section .. Setup code, not for display >>> conn.close() - ROLLBACK \ No newline at end of file + ROLLBACK + +.. _queryguide_additional: + +Additional ORM API Constructs +============================= + + +.. autofunction:: sqlalchemy.orm.aliased + +.. autoclass:: sqlalchemy.orm.util.AliasedClass + +.. autoclass:: sqlalchemy.orm.util.AliasedInsp + +.. autoclass:: sqlalchemy.orm.Bundle + :members: + +.. autoclass:: sqlalchemy.orm.Load + :members: + +.. autofunction:: sqlalchemy.orm.with_loader_criteria + +.. autofunction:: join + +.. autofunction:: outerjoin + +.. autofunction:: with_parent + diff --git a/doc/build/orm/session_basics.rst b/doc/build/orm/session_basics.rst index 8102832d20..fce6d4919d 100644 --- a/doc/build/orm/session_basics.rst +++ b/doc/build/orm/session_basics.rst @@ -547,21 +547,7 @@ objects in the application. The :class:`_orm.Session` can also emit UPDATE and DELETE statements with arbitrary WHERE clauses as well, and at the same time refresh locally present objects which match those rows. -To emit an ORM-enabled UPDATE in :term:`1.x style`, the :meth:`_query.Query.update` method -may be used:: - - session.query(User).filter(User.name == "squidward").\ - update({"name": "spongebob"}, synchronize_session="fetch") - -Above, an UPDATE will be emitted against all rows that match the name -"squidward" and be updated to the name "spongebob". The -:paramref:`_query.Query.update.synchronize_session` parameter referring to -"fetch" indicates the list of affected primary keys should be fetched either -via a separate SELECT statement or via RETURNING if the backend database supports it; -objects locally present in memory will be updated in memory based on these -primary key identities. - -For ORM-enabled UPDATEs in :term:`2.0 style`, :meth:`_orm.Session.execute` is used with the +To emit an ORM-enabled UPDATE, :meth:`_orm.Session.execute` is used with the Core :class:`_sql.Update` construct:: from sqlalchemy import update @@ -571,8 +557,13 @@ Core :class:`_sql.Update` construct:: result = session.execute(stmt) -Above, the :meth:`_dml.Update.execution_options` method may be used to -establish execution-time options such as "synchronize_session". +Above, an UPDATE will be emitted against all rows that match the name +"squidward" and be updated to the name "spongebob". The +special execution option ``synchronize_session`` referring to +"fetch" indicates the list of affected primary keys should be fetched either +via a separate SELECT statement or via RETURNING if the backend database supports it; +objects locally present in memory will be updated in memory based on these +primary key identities. The result object returned is an instance of :class:`_result.CursorResult`; to retrieve the number of rows matched by any UPDATE or DELETE statement, use @@ -584,12 +575,7 @@ DELETEs work in the same way as UPDATE except there is no "values / set" clause established. When synchronize_session is used, matching objects within the :class:`_orm.Session` will be marked as deleted and expunged. -ORM-enabled delete, :term:`1.x style`:: - - session.query(User).filter(User.name == "squidward").\ - delete(synchronize_session="fetch") - -ORM-enabled delete, :term:`2.0 style`:: +ORM-enabled delete:: from sqlalchemy import delete diff --git a/doc/build/orm/tutorial.rst b/doc/build/orm/tutorial.rst new file mode 100644 index 0000000000..0ee0216e96 --- /dev/null +++ b/doc/build/orm/tutorial.rst @@ -0,0 +1,12 @@ +.. _ormtutorial_toplevel: + +========================== +Object Relational Tutorial +========================== + +.. admonition:: We've Moved! + + This page is the previous home of the SQLAlchemy 1.x Tutorial. As of 2.0, + SQLAlchemy presents a revised way of working and an all new tutorial that + presents Core and ORM in an integrated fashion using all the latest usage + patterns. See :ref:`unified_tutorial`. diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index bd897211ca..c987f6b166 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -101,9 +101,6 @@ class Query( :meth:`_query.Query.with_session` method. - For a full walk through of :class:`_query.Query` usage, see the - :ref:`ormtutorial_toplevel`. - """ # elements that are in Core and can be cached in the same way @@ -2290,17 +2287,6 @@ class Query( .. note:: This flag is considered legacy. - .. seealso:: - - :ref:`ormtutorial_joins` in the ORM tutorial. - - :ref:`inheritance_toplevel` for details on how - :meth:`_query.Query.join` is used for inheritance relationships. - - :func:`_orm.join` - a standalone ORM-level join function, - used internally by :meth:`_query.Query.join`, which in previous - SQLAlchemy versions was the primary ORM-level joining interface. - """ aliased, from_joinpoint, isouter, full = ( @@ -2772,11 +2758,6 @@ class Query( appropriate to the entity class represented by this :class:`_query.Query`. - .. seealso:: - - :ref:`orm_tutorial_literal_sql` - usage examples in the - ORM tutorial - """ statement = coercions.expect( roles.SelectStatementRole, statement, apply_propagate_attrs=self @@ -3117,8 +3098,6 @@ class Query( :ref:`faq_query_deduplicating` - :ref:`orm_tutorial_query_returning` - For fine grained control over specific columns to count, to skip the usage of a subquery or otherwise control of the FROM clause, or to use other aggregate functions, use :attr:`~sqlalchemy.sql.expression.func` diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index 95d329ab0d..8be5fbee72 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -2042,6 +2042,18 @@ class Session(_SessionClassMethods): """Return a new :class:`_query.Query` object corresponding to this :class:`_orm.Session`. + Note that the :class:`_query.Query` object is legacy as of + SQLAlchemy 2.0; the :func:`_sql.select` construct is now used + to construct ORM queries. + + .. seealso:: + + :ref:`unified_tutorial` + + :ref:`queryguide_toplevel` + + :ref:`query_api_toplevel` - legacy API doc + """ return self._query_cls(entities, self, **kwargs)