diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-01-05 14:11:12 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-01-05 14:11:12 -0500 |
commit | 196f7ee6cc132aa0f31741af80fa5c0ba77efcf2 (patch) | |
tree | ef4b141ad83f1698b89f0e247f99475a0621a951 | |
parent | 7658a4c73c1e60cc4549389a72a2af26acfa51fc (diff) | |
download | sqlalchemy-196f7ee6cc132aa0f31741af80fa5c0ba77efcf2.tar.gz |
- conjunctions like and_() and or_() can now accept generators as arguments.
-rw-r--r-- | doc/build/changelog/changelog_09.rst | 11 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/elements.py | 1 | ||||
-rw-r--r-- | lib/sqlalchemy/util/__init__.py | 3 | ||||
-rw-r--r-- | lib/sqlalchemy/util/_collections.py | 7 | ||||
-rw-r--r-- | test/sql/test_compiler.py | 11 |
5 files changed, 32 insertions, 1 deletions
diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index 2dbb9702d..97da9e20c 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -17,6 +17,17 @@ .. change:: :tags: feature, core + Conjunctions like :func:`.and_` and :func:`.or_` can now accept + Python generators as a single argument, e.g.:: + + and_(x == y for x, y in tuples) + + The logic here looks for a single argument ``*args`` where the first + element is an instance of ``types.GeneratorType``. + + .. change:: + :tags: feature, core + The :paramref:`.Table.extend_existing` and :paramref:`.Table.autoload_replace` parameters are now available on the :meth:`.MetaData.reflect` method. diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index 56fca5dd8..c230802cc 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -1492,6 +1492,7 @@ class BooleanClauseList(ClauseList, ColumnElement): def _construct(cls, operator, continue_on, skip_on, *clauses, **kw): convert_clauses = [] + clauses = util.coerce_generator_arg(clauses) for clause in clauses: clause = _literal_as_text(clause) diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py index 77339e56a..fdf0c9dac 100644 --- a/lib/sqlalchemy/util/__init__.py +++ b/lib/sqlalchemy/util/__init__.py @@ -18,7 +18,8 @@ from ._collections import KeyedTuple, ImmutableContainer, immutabledict, \ column_dict, ordered_column_set, populate_column_dict, unique_list, \ UniqueAppender, PopulateDict, EMPTY_SET, to_list, to_set, \ to_column_set, update_copy, flatten_iterator, \ - LRUCache, ScopedRegistry, ThreadLocalRegistry, WeakSequence + LRUCache, ScopedRegistry, ThreadLocalRegistry, WeakSequence, \ + coerce_generator_arg from .langhelpers import iterate_attributes, class_hierarchy, \ portable_instancemethod, unbound_method_to_callable, \ diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py index a43115203..24a3c1767 100644 --- a/lib/sqlalchemy/util/_collections.py +++ b/lib/sqlalchemy/util/_collections.py @@ -6,10 +6,12 @@ """Collection classes and helpers.""" +from __future__ import absolute_import import weakref import operator from .compat import threading, itertools_filterfalse from . import py2k +import types EMPTY_SET = frozenset() @@ -754,6 +756,11 @@ class UniqueAppender(object): def __iter__(self): return iter(self.data) +def coerce_generator_arg(arg): + if len(arg) == 1 and isinstance(arg[0], types.GeneratorType): + return list(arg[0]) + else: + return arg def to_list(x, default=None): if x is None: diff --git a/test/sql/test_compiler.py b/test/sql/test_compiler.py index a5916c825..53b9f68fc 100644 --- a/test/sql/test_compiler.py +++ b/test/sql/test_compiler.py @@ -853,6 +853,17 @@ class SelectTest(fixtures.TestBase, AssertsCompiledSQL): 'otherid_1': 9, 'myid_1': 12} ) + # test a generator + self.assert_compile( + and_( + conj for conj in [ + table1.c.myid == 12, + table1.c.name == 'asdf' + ] + ), + "mytable.myid = :myid_1 AND mytable.name = :name_1" + ) + def test_nested_conjunctions_short_circuit(self): """test that empty or_(), and_() conjunctions are collapsed by an enclosing conjunction.""" |