diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-07-08 14:31:17 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-07-11 14:55:51 -0400 |
commit | 5de0f1cf50cc0170d8ea61304e7b887259ab577b (patch) | |
tree | d351743b4ce2009584ef494ab33a6c3f81ab6bb4 /lib/sqlalchemy/sql/elements.py | |
parent | e2d4b2e72cb97bc5612fa9d1ec7d0ab15d38efe1 (diff) | |
download | sqlalchemy-5de0f1cf50cc0170d8ea61304e7b887259ab577b.tar.gz |
Convert remaining ORM APIs to support 2.0 style
This is kind of a mixed bag of all kinds to help get us
to 1.4 betas. The documentation stuff is a work in
progress. Lots of other relatively small changes to
APIs and things. More commits will follow to continue
improving the documentation and transitioning to the
1.4/2.0 hybrid documentation. In particular some refinements
to Session usage models so that it can match Engine's
scoping / transactional patterns, and a decision to
start moving away from "subtransactions" completely.
* add select().from_statement() to produce FromStatement in an
ORM context
* begin referring to select() that has "plugins" for the few edge
cases where select() will have ORM-only behaviors
* convert dynamic.AppenderQuery to its own object that can use
select(), though at the moment it uses Query to support legacy
join calling forms.
* custom query classes for AppenderQuery are replaced by
do_orm_execute() hooks for custom actions, a separate gerrit
will document this
* add Session.get() to replace query.get()
* Deprecate session.begin->subtransaction. propose within the
test suite a hypothetical recipe for apps that rely on this
pattern
* introduce Session construction level context manager,
sessionmaker context manager, rewrite the whole top of the
session_transaction.rst documentation. Establish context manager
patterns for Session that are identical to engine
* ensure same begin_nested() / commit() behavior as engine
* devise all new "join into an external transaction" recipe,
add test support for it, add rules into Session so it
just works, write new docs. need to ensure this doesn't
break anything
* vastly reduce the verbosity of lots of session docs as
I dont think people read this stuff and it's difficult
to keep current in any case
* constructs like case(), with_only_columns() really need
to move to *columns, add a coercion rule to just change
these.
* docs need changes everywhere I look. in_() is not in
the Core tutorial? how do people even know about it?
Remove tons of cruft from Select docs, etc.
* build a system for common ORM options like populate_existing
and autoflush to populate from execution options.
* others?
Change-Id: Ia4bea0f804250e54d90b3884cf8aab8b66b82ecf
Diffstat (limited to 'lib/sqlalchemy/sql/elements.py')
-rw-r--r-- | lib/sqlalchemy/sql/elements.py | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index 6ce505412..c7e5aabcc 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -2573,10 +2573,8 @@ class Case(ColumnElement): stmt = select([users_table]).\ where( case( - [ - (users_table.c.name == 'wendy', 'W'), - (users_table.c.name == 'jack', 'J') - ], + (users_table.c.name == 'wendy', 'W'), + (users_table.c.name == 'jack', 'J'), else_='E' ) ) @@ -2597,7 +2595,10 @@ class Case(ColumnElement): ("else_", InternalTraversal.dp_clauseelement), ] - def __init__(self, whens, value=None, else_=None): + # TODO: for Py2k removal, this will be: + # def __init__(self, *whens, value=None, else_=None): + + def __init__(self, *whens, **kw): r"""Produce a ``CASE`` expression. The ``CASE`` construct in SQL is a conditional object that @@ -2612,10 +2613,8 @@ class Case(ColumnElement): stmt = select([users_table]).\ where( case( - [ - (users_table.c.name == 'wendy', 'W'), - (users_table.c.name == 'jack', 'J') - ], + (users_table.c.name == 'wendy', 'W'), + (users_table.c.name == 'jack', 'J'), else_='E' ) ) @@ -2660,16 +2659,14 @@ class Case(ColumnElement): from sqlalchemy import case, literal_column case( - [ - ( - orderline.c.qty > 100, - literal_column("'greaterthan100'") - ), - ( - orderline.c.qty > 10, - literal_column("'greaterthan10'") - ) - ], + ( + orderline.c.qty > 100, + literal_column("'greaterthan100'") + ), + ( + orderline.c.qty > 10, + literal_column("'greaterthan10'") + ), else_=literal_column("'lessthan10'") ) @@ -2683,19 +2680,23 @@ class Case(ColumnElement): ELSE 'lessthan10' END - :param whens: The criteria to be compared against, + :param \*whens: The criteria to be compared against, :paramref:`.case.whens` accepts two different forms, based on whether or not :paramref:`.case.value` is used. + .. versionchanged:: 1.4 the :func:`_sql.case` + function now accepts the series of WHEN conditions positionally; + passing the expressions within a list is deprecated. + In the first form, it accepts a list of 2-tuples; each 2-tuple consists of ``(<sql expression>, <value>)``, where the SQL expression is a boolean expression and "value" is a resulting value, e.g.:: - case([ + case( (users_table.c.name == 'wendy', 'W'), (users_table.c.name == 'jack', 'J') - ]) + ) In the second form, it accepts a Python dictionary of comparison values mapped to a resulting value; this form requires @@ -2720,11 +2721,23 @@ class Case(ColumnElement): """ + if "whens" in kw: + util.warn_deprecated_20( + 'The "whens" argument to case() is now passed as a series of ' + "positional " + "elements, rather than as a list. " + ) + whens = kw.pop("whens") + else: + whens = coercions._expression_collection_was_a_list( + "whens", "case", whens + ) try: whens = util.dictlike_iteritems(whens) except TypeError: pass + value = kw.pop("value", None) if value is not None: whenlist = [ ( @@ -2760,11 +2773,16 @@ class Case(ColumnElement): self.type = type_ self.whens = whenlist + + else_ = kw.pop("else_", None) if else_ is not None: self.else_ = coercions.expect(roles.ExpressionElementRole, else_) else: self.else_ = None + if kw: + raise TypeError("unknown arguments: %s" % (", ".join(sorted(kw)))) + @property def _from_objects(self): return list( |