diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-12-09 18:05:00 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-12-22 11:31:13 -0500 |
| commit | 60e7034a7423955cd89d5624f8769d3804ca6d82 (patch) | |
| tree | 027fd963fc073970b9ab62ae7f389e61192b1992 /lib/sqlalchemy/engine/create.py | |
| parent | c6554ac52bfb7ce9ecd30ec777ce90adfe7861d2 (diff) | |
| download | sqlalchemy-60e7034a7423955cd89d5624f8769d3804ca6d82.tar.gz | |
Use expanding IN for all literal value IN expressions
The "expanding IN" feature, which generates IN expressions at query
execution time which are based on the particular parameters associated with
the statement execution, is now used for all IN expressions made against
lists of literal values. This allows IN expressions to be fully cacheable
independently of the list of values being passed, and also includes support
for empty lists. For any scenario where the IN expression contains
non-literal SQL expressions, the old behavior of pre-rendering for each
position in the IN is maintained. The change also completes support for
expanding IN with tuples, where previously type-specific bind processors
weren't taking effect.
As part of this change, a more explicit separation between
"literal execute" and "post compile" bound parameters is being made;
as the "ansi bind rules" feature is rendering bound parameters
inline, as we now support "postcompile" generically, these should
be used here, however we have to render literal values at
execution time even for "expanding" parameters. new test fixtures
etc. are added to assert everything goes to the right place.
Fixes: #4645
Change-Id: Iaa2b7bfbfaaf5b80799ee17c9b8507293cba6ed1
Diffstat (limited to 'lib/sqlalchemy/engine/create.py')
| -rw-r--r-- | lib/sqlalchemy/engine/create.py | 32 |
1 files changed, 14 insertions, 18 deletions
diff --git a/lib/sqlalchemy/engine/create.py b/lib/sqlalchemy/engine/create.py index fd6105561..1378a6799 100644 --- a/lib/sqlalchemy/engine/create.py +++ b/lib/sqlalchemy/engine/create.py @@ -23,7 +23,16 @@ from .. import util ":func:`.create_mock_engine` going forward. For general " "customization of create_engine which may have been accomplished " "using strategies, see :class:`.CreateEnginePlugin`.", - ) + ), + empty_in_strategy=( + "1.4", + "The :paramref:`.create_engine.empty_in_strategy` keyword is " + "deprecated, and no longer has any effect. All IN expressions " + "are now rendered using " + 'the "expanding parameter" strategy which renders a set of bound' + 'expressions, or an "empty set" SELECT, at statement execution' + "time.", + ), ) def create_engine(url, **kwargs): """Create a new :class:`.Engine` instance. @@ -130,23 +139,8 @@ def create_engine(url, **kwargs): logging. - :param empty_in_strategy: The SQL compilation strategy to use when - rendering an IN or NOT IN expression for :meth:`.ColumnOperators.in_` - where the right-hand side - is an empty set. This is a string value that may be one of - ``static``, ``dynamic``, or ``dynamic_warn``. The ``static`` - strategy is the default, and an IN comparison to an empty set - will generate a simple false expression "1 != 1". The ``dynamic`` - strategy behaves like that of SQLAlchemy 1.1 and earlier, emitting - a false expression of the form "expr != expr", which has the effect - of evaluting to NULL in the case of a null expression. - ``dynamic_warn`` is the same as ``dynamic``, however also emits a - warning when an empty set is encountered; this because the "dynamic" - comparison is typically poorly performing on most databases. - - .. versionadded:: 1.2 Added the ``empty_in_strategy`` setting and - additionally defaulted the behavior for empty-set IN comparisons - to a static boolean expression. + :param empty_in_strategy: No longer used; SQLAlchemy now uses + "empty set" behavior for IN in all cases. :param encoding: Defaults to ``utf-8``. This is the string encoding used by SQLAlchemy for string encode/decode @@ -412,6 +406,8 @@ def create_engine(url, **kwargs): else: raise exc.ArgumentError("unknown strategy: %r" % strat) + kwargs.pop("empty_in_strategy", None) + # create url.URL object u = _url.make_url(url) |
