]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- conjunctions like and_() and or_() can now accept generators as arguments.
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 5 Jan 2014 19:11:12 +0000 (14:11 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 5 Jan 2014 19:11:12 +0000 (14:11 -0500)
doc/build/changelog/changelog_09.rst
lib/sqlalchemy/sql/elements.py
lib/sqlalchemy/util/__init__.py
lib/sqlalchemy/util/_collections.py
test/sql/test_compiler.py

index 2dbb9702daefa1e738be7397378e18ae2edd4f27..97da9e20c28ac2334adbf82c2115093ff267bafb 100644 (file)
 .. changelog::
     :version: 0.9.1
 
+    .. 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
 
index 56fca5dd8d2d83eaf5ed95cda28d2d4cfcedfd77..c230802ccd73f8cf996ed5c55d8bec9c8ac1c032 100644 (file)
@@ -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)
 
index 77339e56a875902e56686f75aad26e47039ea6b6..fdf0c9dac91d22eebfb9c19f81f7031c52e6d758 100644 (file)
@@ -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, \
index a43115203aecf21e78704801289635abe4e9242a..24a3c1767c534fa9b07ee66b321b19e50fcf5a37 100644 (file)
@@ -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:
index a5916c825659050e4dcec91e693b8b9d4e3235cb..53b9f68fc615441980b13fcdcb8a7fb4538ebc93 100644 (file)
@@ -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."""