]> 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:57:15 +0000 (10:57 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 8 Jan 2013 15:57:15 +0000 (10:57 -0500)
where an entity may be ``None`` without throwing an error.

[ticket:2640]

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

index b62e86df6b819be813e906476a3c61dcc0734cf2..fdf5c1fa28329e05989487f796c42e106476d874 100644 (file)
       to the MSSQL dialect's "schema rendering"
       logic's failure to take .key into account.
 
+    .. 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 1be9777f44dc9deefb7e0af77d481d5a2fba99ec..286dbf6b3e2410861cb019fc0106dfae20b4d649 100644 (file)
@@ -2419,10 +2419,11 @@ class Query(object):
                 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.NamedTuple(newrow, keys))
 
             return iter(result)
index 77afa17a0c55198a03da5b3f27f80024635d0c7a..7b401a7cc12a02fb6070b0bb29146e822d855324 100644 (file)
@@ -1,5 +1,5 @@
 from test.orm import _fixtures
-from sqlalchemy.orm import Session, mapper
+from sqlalchemy.orm import Session, mapper, aliased
 from test.lib.testing import eq_
 from sqlalchemy.util import NamedTuple
 
@@ -89,3 +89,24 @@ 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: NamedTuple(x, ['User', 'useralias'])
+        collection = [kt(u1, u2), kt(u1, None), kt(u2, u3)]
+        it = q.merge_result(
+            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)]
+        )
+
+