diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-08-18 13:56:50 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-09-25 19:38:10 -0400 |
commit | 81d8394c0b5342cdc603cb2e07e12139c9506bf6 (patch) | |
tree | 5453f51ef80bb3b0b4705025070439fdccfea29c /lib/sqlalchemy/orm/scoping.py | |
parent | a8029f5a7e3e376ec57f1614ab0294b717d53c05 (diff) | |
download | sqlalchemy-81d8394c0b5342cdc603cb2e07e12139c9506bf6.tar.gz |
New ORM Query Guide featuring DML support
reviewers: these docs publish periodically at:
https://docs.sqlalchemy.org/en/gerrit/4042/orm/queryguide/index.html
See the "last generated" timestamp near the bottom of the
page to ensure the latest version is up
Change includes some other adjustments:
* small typing fixes for end-user benefit
* removal of a bunch of old examples for patterns that nobody
uses or aren't really what we promote now
* modernization of some examples, including inheritance
Change-Id: I9929daab7797be9515f71c888b28af1209e789ff
Diffstat (limited to 'lib/sqlalchemy/orm/scoping.py')
-rw-r--r-- | lib/sqlalchemy/orm/scoping.py | 170 |
1 files changed, 46 insertions, 124 deletions
diff --git a/lib/sqlalchemy/orm/scoping.py b/lib/sqlalchemy/orm/scoping.py index c00508385..abe97653a 100644 --- a/lib/sqlalchemy/orm/scoping.py +++ b/lib/sqlalchemy/orm/scoping.py @@ -1124,44 +1124,19 @@ class scoped_session(Generic[_S]): Proxied for the :class:`_orm.Session` class on behalf of the :class:`_orm.scoping.scoped_session` class. - The bulk save feature allows mapped objects to be used as the - source of simple INSERT and UPDATE operations which can be more easily - grouped together into higher performing "executemany" - operations; the extraction of data from the objects is also performed - using a lower-latency process that ignores whether or not attributes - have actually been modified in the case of UPDATEs, and also ignores - SQL expressions. - - The objects as given are not added to the session and no additional - state is established on them. If the - :paramref:`_orm.Session.bulk_save_objects.return_defaults` flag is set, - then server-generated primary key values will be assigned to the - returned objects, but **not server side defaults**; this is a - limitation in the implementation. If stateful objects are desired, - please use the standard :meth:`_orm.Session.add_all` approach or - as an alternative newer mass-insert features such as - :ref:`orm_dml_returning_objects`. - - .. warning:: - - The bulk save feature allows for a lower-latency INSERT/UPDATE - of rows at the expense of most other unit-of-work features. - Features such as object management, relationship handling, - and SQL clause support are **silently omitted** in favor of raw - INSERT/UPDATES of records. - - Please note that newer versions of SQLAlchemy are **greatly - improving the efficiency** of the standard flush process. It is - **strongly recommended** to not use the bulk methods as they - represent a forking of SQLAlchemy's functionality and are slowly - being moved into legacy status. New features such as - :ref:`orm_dml_returning_objects` are both more efficient than - the "bulk" methods and provide more predictable functionality. - - **Please read the list of caveats at** - :ref:`bulk_operations_caveats` **before using this method, and - fully test and confirm the functionality of all code developed - using these systems.** + .. 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 @@ -1203,11 +1178,9 @@ class scoped_session(Generic[_S]): False, common types of objects are grouped into inserts and updates, to allow for more batching opportunities. - .. versionadded:: 1.3 - .. seealso:: - :ref:`bulk_operations` + :doc:`queryguide/dml` :meth:`.Session.bulk_insert_mappings` @@ -1237,41 +1210,14 @@ class scoped_session(Generic[_S]): Proxied for the :class:`_orm.Session` class on behalf of the :class:`_orm.scoping.scoped_session` class. - The bulk insert feature allows plain Python dictionaries to be used as - the source of simple INSERT operations which can be more easily - grouped together into higher performing "executemany" - operations. Using dictionaries, there is no "history" or session - state management features in use, reducing latency when inserting - large numbers of simple rows. - - The values within the dictionaries as given are typically passed - without modification into Core :meth:`_expression.Insert` constructs, - after - organizing the values within them across the tables to which - the given mapper is mapped. - - .. versionadded:: 1.0.0 - - .. warning:: - - The bulk insert feature allows for a lower-latency INSERT - of rows at the expense of most other unit-of-work features. - Features such as object management, relationship handling, - and SQL clause support are **silently omitted** in favor of raw - INSERT of records. - - Please note that newer versions of SQLAlchemy are **greatly - improving the efficiency** of the standard flush process. It is - **strongly recommended** to not use the bulk methods as they - represent a forking of SQLAlchemy's functionality and are slowly - being moved into legacy status. New features such as - :ref:`orm_dml_returning_objects` are both more efficient than - the "bulk" methods and provide more predictable functionality. - - **Please read the list of caveats at** - :ref:`bulk_operations_caveats` **before using this method, and - fully test and confirm the functionality of all code developed - using these systems.** + .. 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, @@ -1284,19 +1230,18 @@ class scoped_session(Generic[_S]): such as a joined-inheritance mapping, each dictionary must contain all keys to be populated into all tables. - :param return_defaults: when True, rows that are missing values which - generate defaults, namely integer primary key defaults and sequences, - will be inserted **one at a time**, so that the primary key value - is available. In particular this will allow joined-inheritance - and other multi-table mappings to insert correctly without the need - to provide primary - key values ahead of time; however, - :paramref:`.Session.bulk_insert_mappings.return_defaults` - **greatly reduces the performance gains** of the method overall. - If the rows - to be inserted only refer to a single table, then there is no - reason this flag should be set as the returned default information - is not used. + :param return_defaults: when True, the INSERT process will be altered + to ensure that newly generated primary key values will be fetched. + The rationale for this parameter is typically to enable + :ref:`Joined Table Inheritance <joined_inheritance>` mappings to + be bulk inserted. + + .. note:: for backends that don't support RETURNING, the + :paramref:`_orm.Session.bulk_insert_mappings.return_defaults` + parameter can significantly decrease performance as INSERT + statements can no longer be batched. See + :ref:`engine_insertmanyvalues` + for background on which backends are affected. :param render_nulls: When True, a value of ``None`` will result in a NULL value being included in the INSERT statement, rather @@ -1320,11 +1265,9 @@ class scoped_session(Generic[_S]): to ensure that no server-side default functions need to be invoked for the operation as a whole. - .. versionadded:: 1.1 - .. seealso:: - :ref:`bulk_operations` + :doc:`queryguide/dml` :meth:`.Session.bulk_save_objects` @@ -1350,35 +1293,14 @@ class scoped_session(Generic[_S]): Proxied for the :class:`_orm.Session` class on behalf of the :class:`_orm.scoping.scoped_session` class. - The bulk update feature allows plain Python dictionaries to be used as - the source of simple UPDATE operations which can be more easily - grouped together into higher performing "executemany" - operations. Using dictionaries, there is no "history" or session - state management features in use, reducing latency when updating - large numbers of simple rows. + .. legacy:: - .. versionadded:: 1.0.0 - - .. warning:: - - The bulk update feature allows for a lower-latency UPDATE - of rows at the expense of most other unit-of-work features. - Features such as object management, relationship handling, - and SQL clause support are **silently omitted** in favor of raw - UPDATES of records. - - Please note that newer versions of SQLAlchemy are **greatly - improving the efficiency** of the standard flush process. It is - **strongly recommended** to not use the bulk methods as they - represent a forking of SQLAlchemy's functionality and are slowly - being moved into legacy status. New features such as - :ref:`orm_dml_returning_objects` are both more efficient than - the "bulk" methods and provide more predictable functionality. - - **Please read the list of caveats at** - :ref:`bulk_operations_caveats` **before using this method, and - fully test and confirm the functionality of all code developed - using these systems.** + 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, @@ -1397,7 +1319,7 @@ class scoped_session(Generic[_S]): .. seealso:: - :ref:`bulk_operations` + :doc:`queryguide/dml` :meth:`.Session.bulk_insert_mappings` @@ -1765,7 +1687,7 @@ class scoped_session(Generic[_S]): def scalars( self, statement: TypedReturnsRows[Tuple[_T]], - params: Optional[_CoreSingleExecuteParams] = None, + params: Optional[_CoreAnyExecuteParams] = None, *, execution_options: _ExecuteOptionsParameter = util.EMPTY_DICT, bind_arguments: Optional[_BindArguments] = None, @@ -1777,7 +1699,7 @@ class scoped_session(Generic[_S]): def scalars( self, statement: Executable, - params: Optional[_CoreSingleExecuteParams] = None, + params: Optional[_CoreAnyExecuteParams] = None, *, execution_options: _ExecuteOptionsParameter = util.EMPTY_DICT, bind_arguments: Optional[_BindArguments] = None, @@ -1788,7 +1710,7 @@ class scoped_session(Generic[_S]): def scalars( self, statement: Executable, - params: Optional[_CoreSingleExecuteParams] = None, + params: Optional[_CoreAnyExecuteParams] = None, *, execution_options: _ExecuteOptionsParameter = util.EMPTY_DICT, bind_arguments: Optional[_BindArguments] = None, |