summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/base.py
diff options
context:
space:
mode:
authormike bayer <mike_mp@zzzcomputing.com>2020-03-11 18:08:03 +0000
committerGerrit Code Review <gerrit@bbpush.zzzcomputing.com>2020-03-11 18:08:03 +0000
commit2aa9a8043b4982d4d7b53e8b11371ea27fccd09c (patch)
tree0fc1f0ddd3a6defdda5888ee48bd4e69bd162c4c /lib/sqlalchemy/sql/base.py
parent59ca6e5fcc6974ea1fac82d05157aa58e550b332 (diff)
parent693938dd6fb2f3ee3e031aed4c62355ac97f3ceb (diff)
downloadsqlalchemy-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.py88
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.