summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/future/selectable.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/future/selectable.py')
-rw-r--r--lib/sqlalchemy/future/selectable.py144
1 files changed, 144 insertions, 0 deletions
diff --git a/lib/sqlalchemy/future/selectable.py b/lib/sqlalchemy/future/selectable.py
new file mode 100644
index 000000000..2b76245e0
--- /dev/null
+++ b/lib/sqlalchemy/future/selectable.py
@@ -0,0 +1,144 @@
+from ..sql import coercions
+from ..sql import roles
+from ..sql.base import _generative
+from ..sql.selectable import GenerativeSelect
+from ..sql.selectable import Select as _LegacySelect
+from ..sql.selectable import SelectState
+from ..sql.util import _entity_namespace_key
+
+
+class Select(_LegacySelect):
+ _is_future = True
+ _setup_joins = ()
+ _legacy_setup_joins = ()
+
+ @classmethod
+ def _create_select(cls, *entities):
+ raise NotImplementedError("use _create_future_select")
+
+ @classmethod
+ def _create_future_select(cls, *entities):
+ r"""Construct a new :class:`_expression.Select` using the 2.
+ x style API.
+
+ .. versionadded:: 2.0 - the :func:`_future.select` construct is
+ the same construct as the one returned by
+ :func:`_expression.select`, except that the function only
+ accepts the "columns clause" entities up front; the rest of the
+ state of the SELECT should be built up using generative methods.
+
+ Similar functionality is also available via the
+ :meth:`_expression.FromClause.select` method on any
+ :class:`_expression.FromClause`.
+
+ .. seealso::
+
+ :ref:`coretutorial_selecting` - Core Tutorial description of
+ :func:`_expression.select`.
+
+ :param \*entities:
+ Entities to SELECT from. For Core usage, this is typically a series
+ of :class:`_expression.ColumnElement` and / or
+ :class:`_expression.FromClause`
+ objects which will form the columns clause of the resulting
+ statement. For those objects that are instances of
+ :class:`_expression.FromClause` (typically :class:`_schema.Table`
+ or :class:`_expression.Alias`
+ objects), the :attr:`_expression.FromClause.c`
+ collection is extracted
+ to form a collection of :class:`_expression.ColumnElement` objects.
+
+ This parameter will also accept :class:`_expression.TextClause`
+ constructs as
+ given, as well as ORM-mapped classes.
+
+ """
+
+ self = cls.__new__(cls)
+ self._raw_columns = [
+ coercions.expect(roles.ColumnsClauseRole, ent, apply_plugins=self)
+ for ent in entities
+ ]
+
+ GenerativeSelect.__init__(self)
+
+ return self
+
+ def filter(self, *criteria):
+ """A synonym for the :meth:`_future.Select.where` method."""
+
+ return self.where(*criteria)
+
+ def _filter_by_zero(self):
+ if self._setup_joins:
+ meth = SelectState.get_plugin_classmethod(
+ self, "determine_last_joined_entity"
+ )
+ _last_joined_entity = meth(self)
+ if _last_joined_entity is not None:
+ return _last_joined_entity
+
+ if self._from_obj:
+ return self._from_obj[0]
+
+ return self._raw_columns[0]
+
+ def filter_by(self, **kwargs):
+ r"""apply the given filtering criterion as a WHERE clause
+ to this select.
+
+ """
+ from_entity = self._filter_by_zero()
+
+ clauses = [
+ _entity_namespace_key(from_entity, key) == value
+ for key, value in kwargs.items()
+ ]
+ return self.filter(*clauses)
+
+ @_generative
+ def join(self, target, onclause=None, isouter=False, full=False):
+ r"""Create a SQL JOIN against this :class:`_expresson.Select`
+ object's criterion
+ and apply generatively, returning the newly resulting
+ :class:`_expression.Select`.
+
+
+ """
+ target = coercions.expect(
+ roles.JoinTargetRole, target, apply_plugins=self
+ )
+ self._setup_joins += (
+ (target, onclause, None, {"isouter": isouter, "full": full}),
+ )
+
+ @_generative
+ def join_from(
+ self, from_, target, onclause=None, isouter=False, full=False
+ ):
+ r"""Create a SQL JOIN against this :class:`_expresson.Select`
+ object's criterion
+ and apply generatively, returning the newly resulting
+ :class:`_expression.Select`.
+
+
+ """
+
+ target = coercions.expect(
+ roles.JoinTargetRole, target, apply_plugins=self
+ )
+ from_ = coercions.expect(
+ roles.FromClauseRole, from_, apply_plugins=self
+ )
+
+ self._setup_joins += (
+ (target, onclause, from_, {"isouter": isouter, "full": full}),
+ )
+
+ def outerjoin(self, target, onclause=None, full=False):
+ """Create a left outer join.
+
+
+
+ """
+ return self.join(target, onclause=onclause, isouter=True, full=full,)