diff options
author | mike bayer <mike_mp@zzzcomputing.com> | 2020-03-11 18:08:03 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@bbpush.zzzcomputing.com> | 2020-03-11 18:08:03 +0000 |
commit | 2aa9a8043b4982d4d7b53e8b11371ea27fccd09c (patch) | |
tree | 0fc1f0ddd3a6defdda5888ee48bd4e69bd162c4c /lib/sqlalchemy/sql/base.py | |
parent | 59ca6e5fcc6974ea1fac82d05157aa58e550b332 (diff) | |
parent | 693938dd6fb2f3ee3e031aed4c62355ac97f3ceb (diff) | |
download | sqlalchemy-2aa9a8043b4982d4d7b53e8b11371ea27fccd09c.tar.gz |
Merge "Rework select(), CompoundSelect() in terms of CompileState"
Diffstat (limited to 'lib/sqlalchemy/sql/base.py')
-rw-r--r-- | lib/sqlalchemy/sql/base.py | 88 |
1 files changed, 86 insertions, 2 deletions
diff --git a/lib/sqlalchemy/sql/base.py b/lib/sqlalchemy/sql/base.py index b61c7dc5e..262dc4a0e 100644 --- a/lib/sqlalchemy/sql/base.py +++ b/lib/sqlalchemy/sql/base.py @@ -47,6 +47,17 @@ class Immutable(object): pass +class SingletonConstant(Immutable): + def __new__(cls, *arg, **kw): + return cls._singleton + + @classmethod + def _create_singleton(cls): + obj = object.__new__(cls) + obj.__init__() + cls._singleton = obj + + class HasMemoized(object): def _reset_memoizations(self): self._memoized_property.expire_instance(self) @@ -60,7 +71,19 @@ class HasMemoized(object): def _from_objects(*elements): - return itertools.chain(*[element._from_objects for element in elements]) + return itertools.chain.from_iterable( + [element._from_objects for element in elements] + ) + + +def _select_iterables(elements): + """expand tables into individual columns in the + given list of column expressions. + + """ + return itertools.chain.from_iterable( + [c._select_iterable for c in elements] + ) def _generative(fn): @@ -421,6 +444,19 @@ class CompileState(object): __slots__ = ("statement",) + @classmethod + def _create(cls, statement, compiler, **kw): + # factory construction. + + # specific CompileState classes here will look for + # "plugins" in the given statement. From there they will invoke + # the appropriate plugin constructor if one is found and return + # the alternate CompileState object. + + c = cls.__new__(cls) + c.__init__(statement, compiler, **kw) + return c + def __init__(self, statement, compiler, **kw): self.statement = statement @@ -434,11 +470,44 @@ class Generative(object): s.__dict__ = self.__dict__.copy() return s + def options(self, *options): + """Apply options to this statement. + + In the general sense, options are any kind of Python object + that can be interpreted by the SQL compiler for the statement. + These options can be consumed by specific dialects or specific kinds + of compilers. + + The most commonly known kind of option are the ORM level options + that apply "eager load" and other loading behaviors to an ORM + query. However, options can theoretically be used for many other + purposes. + + For background on specific kinds of options for specific kinds of + statements, refer to the documentation for those option objects. + + .. versionchanged:: 1.4 - added :meth:`.Generative.options` to + Core statement objects towards the goal of allowing unified + Core / ORM querying capabilities. + + .. seealso:: + + :ref:`deferred_options` - refers to options specific to the usage + of ORM queries + + :ref:`relationship_loader_options` - refers to options specific + to the usage of ORM queries + + """ + self._options += options + class HasCompileState(Generative): """A class that has a :class:`.CompileState` associated with it.""" - _compile_state_cls = CompileState + _compile_state_factory = CompileState._create + + _compile_state_plugin = None class Executable(Generative): @@ -511,6 +580,13 @@ class Executable(Generative): """ return self._execution_options + @util.deprecated_20( + ":meth:`.Executable.execute`", + alternative="All statement execution in SQLAlchemy 2.0 is performed " + "by the :meth:`.Connection.execute` method of :class:`.Connection`, " + "or in the ORM by the :meth:`.Session.execute` method of " + ":class:`.Session`.", + ) def execute(self, *multiparams, **params): """Compile and execute this :class:`.Executable`.""" e = self.bind @@ -524,6 +600,14 @@ class Executable(Generative): raise exc.UnboundExecutionError(msg) return e._execute_clauseelement(self, multiparams, params) + @util.deprecated_20( + ":meth:`.Executable.scalar`", + alternative="All statement execution in SQLAlchemy 2.0 is performed " + "by the :meth:`.Connection.execute` method of :class:`.Connection`, " + "or in the ORM by the :meth:`.Session.execute` method of " + ":class:`.Session`; the :meth:`.Result.scalar` method can then be " + "used to return a scalar result.", + ) def scalar(self, *multiparams, **params): """Compile and execute this :class:`.Executable`, returning the result's scalar representation. |