]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Check for column object in eval_none, not propkey
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 18 Jul 2017 15:41:12 +0000 (11:41 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 18 Jul 2017 19:04:55 +0000 (15:04 -0400)
Fixed bug involving JSON NULL evaluation logic added in 1.1 as part
of :ticket:`3514` where the logic would not accommodate ORM
mapped attributes named differently from the :class:`.Column`
that was mapped.

Change-Id: I1848afcfb63ad7f074f315d8d3097666069b42be
Fixes: #4031
(cherry picked from commit e2ede596adff3ce584f8c43ba024cafabc509a06)

doc/build/changelog/changelog_11.rst
lib/sqlalchemy/orm/mapper.py
lib/sqlalchemy/orm/persistence.py
test/orm/test_unitofworkv2.py

index 14606f86cfc70e9755be51d3c0e45f6eeac8d706..6ca43b36a5c0cb3a85ff4c25273349d747fdd02c 100644 (file)
         ORDER parameter understood by Oracle.  Pull request
         courtesy David Moore.
 
+    .. change:: 4031
+        :tags: bug, orm
+        :versions: 1.2.0b2
+        :tickets: 4031
+
+        Fixed bug involving JSON NULL evaluation logic added in 1.1 as part
+        of :ticket:`3514` where the logic would not accommodate ORM
+        mapped attributes named differently from the :class:`.Column`
+        that was mapped.
+
+
 .. changelog::
     :version: 1.1.11
     :released: Monday, June 19, 2017
index 596d5faa977001b320097d979ca636c176ee376c..3f0c866d161c702549fa7e5aa6e0abbe081701d4 100644 (file)
@@ -1975,7 +1975,7 @@ class Mapper(InspectionAttr):
             (
                 table,
                 frozenset(
-                    col.key for col in columns
+                    col for col in columns
                     if col.type.should_evaluate_none
                 )
             )
index ad268c127330e27015df2702875668ca4378449c..9ce277133272217314b9a2e5346c3287dbbbbafd 100644 (file)
@@ -391,7 +391,7 @@ def _collect_insert_commands(
         for propkey in set(propkey_to_col).intersection(state_dict):
             value = state_dict[propkey]
             col = propkey_to_col[propkey]
-            if value is None and propkey not in eval_none and not render_nulls:
+            if value is None and col not in eval_none and not render_nulls:
                 continue
             elif not bulk and hasattr(value, '__clause_element__') or \
                     isinstance(value, sql.ClauseElement):
index ecd3650003db23b0e2b82cb833df6bf396a54236..270c3708e5aad95edfe58af39844646a913f4ed1 100644 (file)
@@ -2501,63 +2501,102 @@ class NullEvaluatingTest(fixtures.MappedTest, testing.AssertsExecutionResults):
                 String(50).evaluates_none(), default='default_val'),
         )
 
+        Table(
+            'test_w_renames', metadata,
+            Column('id', Integer, primary_key=True,
+                   test_needs_autoincrement=True),
+            Column('evals_null_no_default', EvalsNull()),
+            Column('evals_null_default', EvalsNull(), default='default_val'),
+            Column('no_eval_null_no_default', String(50)),
+            Column('no_eval_null_default', String(50), default='default_val'),
+            Column(
+                'builtin_evals_null_no_default', String(50).evaluates_none()),
+            Column(
+                'builtin_evals_null_default',
+                String(50).evaluates_none(), default='default_val'),
+        )
+
     @classmethod
     def setup_classes(cls):
         class Thing(cls.Basic):
             pass
 
+        class AltNameThing(cls.Basic):
+            pass
+
     @classmethod
     def setup_mappers(cls):
         Thing = cls.classes.Thing
+        AltNameThing = cls.classes.AltNameThing
 
         mapper(Thing, cls.tables.test)
 
+        mapper(AltNameThing, cls.tables.test_w_renames, column_prefix="_foo_")
+
     def _assert_col(self, name, value):
-        Thing = self.classes.Thing
+        Thing, AltNameThing = self.classes.Thing, self.classes.AltNameThing
         s = Session()
 
         col = getattr(Thing, name)
         obj = s.query(col).filter(col == value).one()
         eq_(obj[0], value)
 
+        col = getattr(AltNameThing, "_foo_" + name)
+        obj = s.query(col).filter(col == value).one()
+        eq_(obj[0], value)
+
     def _test_insert(self, attr, expected):
-        Thing = self.classes.Thing
+        Thing, AltNameThing = self.classes.Thing, self.classes.AltNameThing
 
         s = Session()
         t1 = Thing(**{attr: None})
         s.add(t1)
+
+        t2 = AltNameThing(**{"_foo_" + attr: None})
+        s.add(t2)
+
         s.commit()
 
         self._assert_col(attr, expected)
 
     def _test_bulk_insert(self, attr, expected):
-        Thing = self.classes.Thing
+        Thing, AltNameThing = self.classes.Thing, self.classes.AltNameThing
 
         s = Session()
         s.bulk_insert_mappings(
             Thing, [{attr: None}]
         )
+        s.bulk_insert_mappings(
+            AltNameThing, [{"_foo_" + attr: None}]
+        )
         s.commit()
 
         self._assert_col(attr, expected)
 
     def _test_insert_novalue(self, attr, expected):
-        Thing = self.classes.Thing
+        Thing, AltNameThing = self.classes.Thing, self.classes.AltNameThing
 
         s = Session()
         t1 = Thing()
         s.add(t1)
+
+        t2 = AltNameThing()
+        s.add(t2)
+
         s.commit()
 
         self._assert_col(attr, expected)
 
     def _test_bulk_insert_novalue(self, attr, expected):
-        Thing = self.classes.Thing
+        Thing, AltNameThing = self.classes.Thing, self.classes.AltNameThing
 
         s = Session()
         s.bulk_insert_mappings(
             Thing, [{}]
         )
+        s.bulk_insert_mappings(
+            AltNameThing, [{}]
+        )
         s.commit()
 
         self._assert_col(attr, expected)