From 8e4e325319eaadb81cc1b6e8c8db7cc1a6b920bd Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 8 Dec 2022 19:31:37 -0500 Subject: add eager_defaults="auto" for inserts Added a new default value for the :paramref:`.Mapper.eager_defaults` parameter "auto", which will automatically fetch table default values during a unit of work flush, if the dialect supports RETURNING for the INSERT being run, as well as :ref:`insertmanyvalues ` available. Eager fetches for server-side UPDATE defaults, which are very uncommon, continue to only take place if :paramref:`.Mapper.eager_defaults` is set to ``True``, as there is no batch-RETURNING form for UPDATE statements. Fixes: #8889 Change-Id: I84b91092a37c4cd216e060513acde3eb0298abe9 --- lib/sqlalchemy/testing/__init__.py | 1 + lib/sqlalchemy/testing/config.py | 53 +++++++++++++++++++++++++++----------- 2 files changed, 39 insertions(+), 15 deletions(-) (limited to 'lib/sqlalchemy/testing') diff --git a/lib/sqlalchemy/testing/__init__.py b/lib/sqlalchemy/testing/__init__.py index 993fc4954..6454750f5 100644 --- a/lib/sqlalchemy/testing/__init__.py +++ b/lib/sqlalchemy/testing/__init__.py @@ -56,6 +56,7 @@ from .config import requirements as requires from .config import skip_test from .config import Variation from .config import variation +from .config import variation_fixture from .exclusions import _is_excluded from .exclusions import _server_version from .exclusions import against as _against diff --git a/lib/sqlalchemy/testing/config.py b/lib/sqlalchemy/testing/config.py index 6adcf5b64..b444eb39f 100644 --- a/lib/sqlalchemy/testing/config.py +++ b/lib/sqlalchemy/testing/config.py @@ -157,9 +157,33 @@ class Variation: def __str__(self): return f"{self._argname}={self._name!r}" + def __repr__(self): + return str(self) + def fail(self) -> NoReturn: fail(f"Unknown {self}") + @classmethod + def idfn(cls, variation): + return variation.name + + @classmethod + def generate_cases(cls, argname, cases): + case_names = [ + argname if c is True else "not_" + argname if c is False else c + for c in cases + ] + + typ = type( + argname, + (Variation,), + { + "__slots__": tuple(case_names), + }, + ) + + return [typ(casename, argname, case_names) for casename in case_names] + def variation(argname, cases): """a helper around testing.combinations that provides a single namespace @@ -203,26 +227,17 @@ def variation(argname, cases): else (entry, None) for entry in cases ] - case_names = [ - argname if c is True else "not_" + argname if c is False else c - for c, l in cases_plus_limitations - ] - typ = type( - argname, - (Variation,), - { - "__slots__": tuple(case_names), - }, + variations = Variation.generate_cases( + argname, [c for c, l in cases_plus_limitations] ) - return combinations( *[ - (casename, typ(casename, argname, case_names), limitation) + (variation._name, variation, limitation) if limitation is not None - else (casename, typ(casename, argname, case_names)) - for casename, (case, limitation) in zip( - case_names, cases_plus_limitations + else (variation._name, variation) + for variation, (case, limitation) in zip( + variations, cases_plus_limitations ) ], id_="ia", @@ -230,6 +245,14 @@ def variation(argname, cases): ) +def variation_fixture(argname, cases, scope="function"): + return fixture( + params=Variation.generate_cases(argname, cases), + ids=Variation.idfn, + scope=scope, + ) + + def fixture(*arg: Any, **kw: Any) -> Any: return _fixture_functions.fixture(*arg, **kw) -- cgit v1.2.1