diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-01-24 14:07:24 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-02-12 12:44:47 -0500 |
commit | 9fca5d827d880ccc529c94bb65c46de6aafd227c (patch) | |
tree | 54383b90c6acfc644c563872f131724fed5ef6ea /lib/sqlalchemy/sql/selectable.py | |
parent | 47202abbf9823e1058e0b88ce64ffd3b88027e96 (diff) | |
download | sqlalchemy-9fca5d827d880ccc529c94bb65c46de6aafd227c.tar.gz |
Create initial future package, RemovedIn20Warning
Reorganization of Select() is the first major element
of the 2.0 restructuring. In order to start this we need
to first create the new Select constructor and apply legacy
elements to the old one. This in turn necessitates
starting up the RemovedIn20Warning concept which itself
need to refer to "sqlalchemy.future", so begin to establish
this basic framework. Additionally, update the
DML constructors with the newer no-keyword style. Remove
the use of the "pending deprecation" and fix Query.add_column()
deprecation which was not acting as deprecated.
Fixes: #4845
Fixes: #4648
Change-Id: I0c7a22b2841a985e1c379a0bb6c94089aae6264c
Diffstat (limited to 'lib/sqlalchemy/sql/selectable.py')
-rw-r--r-- | lib/sqlalchemy/sql/selectable.py | 125 |
1 files changed, 95 insertions, 30 deletions
diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py index db743f408..b2ec32c13 100644 --- a/lib/sqlalchemy/sql/selectable.py +++ b/lib/sqlalchemy/sql/selectable.py @@ -369,7 +369,8 @@ class FromClause(HasMemoized, roles.AnonymizedFromClauseRole, Selectable): col = list(self.primary_key)[0] else: col = list(self.columns)[0] - return Select( + return Select._create_select_from_fromclause( + self, [functions.func.count(col).label("tbl_row_count")], whereclause, from_obj=[self], @@ -1018,7 +1019,11 @@ class Join(FromClause): """ collist = [self.left, self.right] - return Select(collist, whereclause, from_obj=[self], **kwargs) + if whereclause is not None: + kwargs["whereclause"] = whereclause + return Select._create_select_from_fromclause( + self, collist, **kwargs + ).select_from(self) @property def bind(self): @@ -1142,7 +1147,7 @@ class Join(FromClause): full=self.full, ) else: - return self.select(use_labels=True, correlate=False).alias(name) + return self.select().apply_labels().correlate(None).alias(name) @property def _hide_froms(self): @@ -1155,6 +1160,21 @@ class Join(FromClause): return [self] + self.left._from_objects + self.right._from_objects +class NoInit(object): + def __init__(self, *arg, **kw): + raise NotImplementedError( + "The %s class is not intended to be constructed " + "directly. Please use the %s() standalone " + "function or the %s() method available from appropriate " + "selectable objects." + % ( + self.__class__.__name__, + self.__class__.__name__.lower(), + self.__class__.__name__.lower(), + ) + ) + + # FromClause -> # AliasedReturnsRows # -> Alias only for FromClause @@ -1163,7 +1183,7 @@ class Join(FromClause): # -> Lateral -> FromClause, but we accept SelectBase # w/ non-deprecated coercion # -> TableSample -> only for FromClause -class AliasedReturnsRows(FromClause): +class AliasedReturnsRows(NoInit, FromClause): """Base class of aliases against tables, subqueries, and other selectables.""" @@ -1175,19 +1195,6 @@ class AliasedReturnsRows(FromClause): ("name", InternalTraversal.dp_anon_name), ] - def __init__(self, *arg, **kw): - raise NotImplementedError( - "The %s class is not intended to be constructed " - "directly. Please use the %s() standalone " - "function or the %s() method available from appropriate " - "selectable objects." - % ( - self.__class__.__name__, - self.__class__.__name__.lower(), - self.__class__.__name__.lower(), - ) - ) - @classmethod def _construct(cls, *arg, **kw): obj = cls.__new__(cls) @@ -3046,7 +3053,7 @@ class DeprecatedSelectGenerations(object): :class:`.Select` object. """ - self.column.non_generative(self, column) + self.add_columns.non_generative(self, column) @util.deprecated( "1.4", @@ -3171,6 +3178,38 @@ class Select( + SupportsCloneAnnotations._traverse_internals ) + @classmethod + def _create_select(cls, *entities): + self = cls.__new__(cls) + self._raw_columns = [ + coercions.expect(roles.ColumnsClauseRole, ent) + for ent in util.to_list(entities) + ] + + # this should all go away once Select is converted to have + # default state at the class level + self._auto_correlate = True + self._from_obj = util.OrderedSet() + self._whereclause = None + self._having = None + + GenerativeSelect.__init__(self) + + return self + + @classmethod + def _create_select_from_fromclause(cls, target, entities, *arg, **kw): + if arg or kw: + util.warn_deprecated_20( + "Passing arguments to %s.select() is deprecated and " + "will be removed in SQLAlchemy 2.0. Please use generative " + "methods such as select().where(), etc." + % (target.__class__.__name__,) + ) + return Select(entities, *arg, **kw) + else: + return Select._create_select(*entities) + @util.deprecated_params( autocommit=( "0.6", @@ -3201,7 +3240,7 @@ class Select( suffixes=None, **kwargs ): - """Construct a new :class:`.Select`. + """Construct a new :class:`.Select` using the 1.x style API. Similar functionality is also available via the :meth:`.FromClause.select` method on any :class:`.FromClause`. @@ -3387,6 +3426,13 @@ class Select( :meth:`.Select.apply_labels` """ + util.warn_deprecated_20( + "The select() function in SQLAlchemy 2.0 will accept a " + "series of columns / tables and other entities only, " + "passed positionally. For forwards compatibility, use the " + "sqlalchemy.future.select() construct." + ) + self._auto_correlate = correlate if distinct is not False: self._distinct = True @@ -3418,8 +3464,6 @@ class Select( self._raw_columns = [] for c in columns: c = coercions.expect(roles.ColumnsClauseRole, c) - if isinstance(c, ScalarSelect): - c = c.self_group(against=operators.comma_op) self._raw_columns.append(c) else: self._raw_columns = [] @@ -3446,7 +3490,6 @@ class Select( GenerativeSelect.__init__(self, **kwargs) - # @_memoized_property @property def _froms(self): # current roadblock to caching is two tests that test that the @@ -3741,13 +3784,13 @@ class Select( ) @_generative - def column(self, column): - """return a new select() construct with the given column expression + def add_columns(self, *columns): + """return a new select() construct with the given column expressions added to its columns clause. E.g.:: - my_select = my_select.column(table.c.new_column) + my_select = my_select.add_columns(table.c.new_column) See the documentation for :meth:`.Select.with_only_columns` for guidelines on adding /replacing the columns of a @@ -3755,12 +3798,32 @@ class Select( """ self._reset_memoizations() - column = coercions.expect(roles.ColumnsClauseRole, column) - if isinstance(column, ScalarSelect): - column = column.self_group(against=operators.comma_op) + self._raw_columns = self._raw_columns + [ + coercions.expect(roles.ColumnsClauseRole, column) + for column in columns + ] + + @util.deprecated( + "1.4", + "The :meth:`.Select.column` method is deprecated and will " + "be removed in a future release. Please use " + ":meth:`.Select.add_columns", + ) + def column(self, column): + """return a new select() construct with the given column expression + added to its columns clause. + + E.g.:: + + my_select = my_select.column(table.c.new_column) + + See the documentation for :meth:`.Select.with_only_columns` + for guidelines on adding /replacing the columns of a + :class:`.Select` object. - self._raw_columns = self._raw_columns + [column] + """ + return self.add_columns(column) @util.dependencies("sqlalchemy.sql.util") def reduce_columns(self, sqlutil, only_synonyms=True): @@ -4340,7 +4403,9 @@ class Exists(UnaryExpression): return element.self_group(against=operators.exists) def select(self, whereclause=None, **params): - return Select([self], whereclause, **params) + if whereclause is not None: + params["whereclause"] = whereclause + return Select._create_select_from_fromclause(self, [self], **params) def correlate(self, *fromclause): e = self._clone() |