]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
fix mapper._primary_key_propkeys
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 29 Apr 2021 16:03:47 +0000 (12:03 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 29 Apr 2021 18:21:50 +0000 (14:21 -0400)
Fixed issue in :meth:`_orm.Session.bulk_save` when used with persistent
objects which would fail to track the primary key of mappings where the
column name of the primary key were different than the attribute name.

Fixes: #6392
Change-Id: I9b89bf00f900b7d2287517249e4f9356f20f0bdb
(cherry picked from commit 7892cc30ad60ae450471b62f351b3beb66911892)

doc/build/changelog/unreleased_13/6392.rst [new file with mode: 0644]
lib/sqlalchemy/orm/mapper.py
test/orm/test_bulk.py

diff --git a/doc/build/changelog/unreleased_13/6392.rst b/doc/build/changelog/unreleased_13/6392.rst
new file mode 100644 (file)
index 0000000..ddd49cc
--- /dev/null
@@ -0,0 +1,9 @@
+.. change::
+    :tags: bug, orm
+    :tickets: 6392
+    :versions: 1.4.12
+
+    Fixed issue in :meth:`_orm.Session.bulk_save` when used with persistent
+    objects which would fail to track the primary key of mappings where the
+    column name of the primary key were different than the attribute name.
+
index c4704b4846ba3371e0b778a1c0708746dd136c48..c2cd208eaad8fa5de03972f79848789dabf854a0 100644 (file)
@@ -2821,7 +2821,7 @@ class Mapper(InspectionAttr):
         return [self._columntoproperty[col] for col in self.primary_key]
 
     @_memoized_configured_property
-    def _all_pk_props(self):
+    def _all_pk_cols(self):
         collection = set()
         for table in self.tables:
             collection.update(self._pks_by_table[table])
@@ -2836,7 +2836,7 @@ class Mapper(InspectionAttr):
 
     @_memoized_configured_property
     def _primary_key_propkeys(self):
-        return {prop.key for prop in self._all_pk_props}
+        return {self._columntoproperty[col].key for col in self._all_pk_cols}
 
     def _get_state_attr_by_column(
         self, state, dict_, column, passive=attributes.PASSIVE_RETURN_NEVER_SET
index 79de19f68403a540112d9999189d9fd8f846194e..611a63adff22ae6875ef22495d195e46ab8159da 100644 (file)
@@ -436,8 +436,15 @@ class BulkUDTestAltColKeys(BulkTest, fixtures.MappedTest):
             )
         )
 
-    def test_update_keys(self):
-        asserter = self._test_update(self.classes.PersonKeys)
+    @testing.combinations(
+        ("states",),
+        ("dicts",),
+    )
+    def test_update_keys(self, type_):
+        if type_ == "states":
+            asserter = self._test_update_states(self.classes.PersonKeys)
+        else:
+            asserter = self._test_update(self.classes.PersonKeys)
         asserter.assert_(
             CompiledSQL(
                 "UPDATE people_keys SET name=:personname "
@@ -446,9 +453,16 @@ class BulkUDTestAltColKeys(BulkTest, fixtures.MappedTest):
             )
         )
 
+    @testing.combinations(
+        ("states",),
+        ("dicts",),
+    )
     @testing.requires.updateable_autoincrement_pks
-    def test_update_attrs(self):
-        asserter = self._test_update(self.classes.PersonAttrs)
+    def test_update_attrs(self, type_):
+        if type_ == "states":
+            asserter = self._test_update_states(self.classes.PersonAttrs)
+        else:
+            asserter = self._test_update(self.classes.PersonAttrs)
         asserter.assert_(
             CompiledSQL(
                 "UPDATE people_attrs SET name=:name "
@@ -499,6 +513,22 @@ class BulkUDTestAltColKeys(BulkTest, fixtures.MappedTest):
 
         return asserter
 
+    def _test_update_states(self, person_cls):
+        Person = person_cls
+
+        s = Session()
+        s.add(Person(id=5, personname="thename"))
+        s.commit()
+
+        p = s.query(Person).get(5)
+        with self.sql_execution_asserter(testing.db) as asserter:
+            p.personname = "newname"
+            s.bulk_save_objects([p])
+
+        eq_(s.query(Person).first(), Person(id=5, personname="newname"))
+
+        return asserter
+
 
 class BulkInheritanceTest(BulkTest, fixtures.MappedTest):
     @classmethod