@@ -230,7 +230,7 @@ def __init__(
230230 passive_updates : bool = True ,
231231 passive_deletes : bool = False ,
232232 confirm_deleted_rows : bool = True ,
233- eager_defaults : bool = False ,
233+ eager_defaults : Literal [ True , False , "auto" ] = "auto" ,
234234 legacy_is_orphan : bool = False ,
235235 _compiled_cache_size : int = 100 ,
236236 ):
@@ -336,14 +336,30 @@ class User(Base):
336336 value of server-generated default values after an INSERT or UPDATE,
337337 rather than leaving them as expired to be fetched on next access.
338338 This can be used for event schemes where the server-generated values
339- are needed immediately before the flush completes. By default,
340- this scheme will emit an individual ``SELECT`` statement per row
341- inserted or updated, which note can add significant performance
342- overhead. However, if the
343- target database supports :term:`RETURNING`, the default values will
344- be returned inline with the INSERT or UPDATE statement, which can
345- greatly enhance performance for an application that needs frequent
346- access to just-generated server defaults.
339+ are needed immediately before the flush completes.
340+
341+ The fetch of values occurs either by using ``RETURNING`` inline
342+ with the ``INSERT`` or ``UPDATE`` statement, or by adding an
343+ additional ``SELECT`` statement subsequent to the ``INSERT`` or
344+ ``UPDATE``, if the backend does not support ``RETURNING``.
345+
346+ The use of ``RETURNING`` is extremely performant in particular for
347+ ``INSERT`` statements where SQLAlchemy can take advantage of
348+ :ref:`insertmanyvalues <engine_insertmanyvalues>`, whereas the use of
349+ an additional ``SELECT`` is relatively poor performing, adding
350+ additional SQL round trips which would be unnecessary if these new
351+ attributes are not to be accessed in any case.
352+
353+ For this reason, :paramref:`.Mapper.eager_defaults` defaults to the
354+ string value ``"auto"``, which indicates that server defaults for
355+ INSERT should be fetched using ``RETURNING`` if the backing database
356+ supports it and if the dialect in use supports "insertmanyreturning"
357+ for an INSERT statement. If the backing database does not support
358+ ``RETURNING`` or "insertmanyreturning" is not available, server
359+ defaults will not be fetched.
360+
361+ .. versionchanged:: 2.0.0b5 added the "auto" option for
362+ :paramref:`.Mapper.eager_defaults`
347363
348364 .. seealso::
349365
@@ -352,6 +368,12 @@ class User(Base):
352368 .. versionchanged:: 0.9.0 The ``eager_defaults`` option can now
353369 make use of :term:`RETURNING` for backends which support it.
354370
371+ .. versionchanged:: 2.0.0 RETURNING now works with multiple rows
372+ INSERTed at once using the
373+ :ref:`insertmanyvalues <engine_insertmanyvalues>` feature, which
374+ among other things allows the :paramref:`.Mapper.eager_defaults`
375+ feature to be very performant on supporting backends.
376+
355377 :param exclude_properties: A list or set of string column names to
356378 be excluded from mapping.
357379
@@ -818,6 +840,18 @@ def generate_version(version):
818840 self ._log ("constructed" )
819841 self ._expire_memoizations ()
820842
843+ def _prefer_eager_defaults (self , dialect , table ):
844+ if self .eager_defaults == "auto" :
845+ if not table .implicit_returning :
846+ return False
847+
848+ return (
849+ table in self ._server_default_col_keys
850+ and dialect .insert_executemany_returning
851+ )
852+ else :
853+ return self .eager_defaults
854+
821855 def _gen_cache_key (self , anon_map , bindparams ):
822856 return (self ,)
823857
0 commit comments