Commits

Mike Bayer committed 176a95a

:meth:`.Query.merge_result` can now load rows from an outer join
where an entity may be ``None`` without throwing an error.

[ticket:2640]

  • Participants
  • Parent commits e754a8a
  • Branches rel_0_7

Comments (0)

Files changed (3)

doc/build/changelog/changelog_07.rst

       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
 

lib/sqlalchemy/orm/query.py

                 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)

test/orm/test_loading.py

 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
 
             [(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)]
+        )
+
+