]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
:meth:`.Query.merge_result` can now load rows from an outer join
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 8 Jan 2013 15:55:46 +0000 (10:55 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 8 Jan 2013 15:55:46 +0000 (10:55 -0500)
where an entity may be ``None`` without throwing an error.
[ticket:2640]

doc/build/changelog/changelog_07.rst
doc/build/changelog/changelog_08.rst
lib/sqlalchemy/orm/loading.py
test/orm/test_loading.py

index c778fb84b9d38cc227d8f0ae181ff8e2a4e62bd4..71bf4e368c052ac02e88e92f7d53f9bed3e8fcae 100644 (file)
@@ -8,6 +8,13 @@
     :version: 0.7.10
     :released:
 
+    .. change::
+        :tags: orm, bug
+        :tickets: 2640
+
+      :meth:`.Query.merge_result` can now load rows from an outer join
+      where an entity may be ``None`` without throwing an error.
+
     .. change::
         :tags: sqlite, bug
         :tickets: 2568
index caed97d60a252cf7f11520f46dc4846029baa12f..b8ae66e44d4aa951a2f307d8c730dc57161714c7 100644 (file)
@@ -6,6 +6,14 @@
 .. changelog::
     :version: 0.8.0
 
+    .. change::
+        :tags: orm, bug
+        :tickets: 2640
+
+      :meth:`.Query.merge_result` can now load rows from an outer join
+      where an entity may be ``None`` without throwing an error.
+      Also in 0.7.10.
+
     .. change::
         :tags: sql, bug
         :tickets: 2648
index baff076eb972021b67222eb32c59a6455532f0d9..5937197fd95220c4af11c0cd8ef19a36dc060047 100644 (file)
@@ -129,10 +129,11 @@ def merge_result(query, iterator, load=True):
             for row in iterator:
                 newrow = list(row)
                 for i in mapped_entities:
-                    newrow[i] = session._merge(
-                            attributes.instance_state(newrow[i]),
-                            attributes.instance_dict(newrow[i]),
-                            load=load, _recursive={})
+                    if newrow[i] is not None:
+                        newrow[i] = session._merge(
+                                attributes.instance_state(newrow[i]),
+                                attributes.instance_dict(newrow[i]),
+                                load=load, _recursive={})
                 result.append(util.KeyedTuple(newrow, keys))
 
         return iter(result)
index 1d2df2c5b6c2b39d31d76d1614f16c579cf79de8..20dc082c5148d716581f3c7cc3d434e076a0848c 100644 (file)
@@ -1,5 +1,5 @@
 from . import _fixtures
-from sqlalchemy.orm import loading, Session
+from sqlalchemy.orm import loading, Session, aliased
 from sqlalchemy.testing.assertions import eq_
 from sqlalchemy.util import KeyedTuple
 
@@ -92,3 +92,25 @@ class MergeResultTest(_fixtures.FixtureTest):
             [(1, 1), (2, 2), (7, 7), (8, 8)]
         )
         eq_(it[0].keys(), ['User', 'id'])
+
+    def test_none_entity(self):
+        s, (u1, u2, u3, u4) = self._fixture()
+        User = self.classes.User
+
+        ua = aliased(User)
+        q = s.query(User, ua)
+        kt = lambda *x: KeyedTuple(x, ['User', 'useralias'])
+        collection = [kt(u1, u2), kt(u1, None), kt(u2, u3)]
+        it = loading.merge_result(
+            q,
+            collection
+        )
+        eq_(
+            [
+                (x and x.id or None, y and y.id or None)
+                for x, y in it
+            ],
+            [(u1.id, u2.id), (u1.id, None), (u2.id, u3.id)]
+        )
+
+