diff options
author | mike bayer <mike_mp@zzzcomputing.com> | 2016-11-10 17:22:41 -0500 |
---|---|---|
committer | Gerrit Code Review <gerrit@awstats.zzzcomputing.com> | 2016-11-10 17:22:41 -0500 |
commit | 03429812125c0265b90f6e1d706d132b88a0161c (patch) | |
tree | f8faa1bf0441abee557b8a4b80031d4b6916f8ec | |
parent | e81660d5c0ace2a805557d6dbb0f190991aaeaec (diff) | |
parent | c9d8a67b52d1f86e694fab4ccab357432941334b (diff) | |
download | sqlalchemy-03429812125c0265b90f6e1d706d132b88a0161c.tar.gz |
Merge "Consider version_id_prop when emitting bulk UPDATE"
-rw-r--r-- | doc/build/changelog/changelog_10.rst | 9 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/persistence.py | 7 | ||||
-rw-r--r-- | test/orm/test_bulk.py | 51 |
3 files changed, 66 insertions, 1 deletions
diff --git a/doc/build/changelog/changelog_10.rst b/doc/build/changelog/changelog_10.rst index 4b28e40a7..bd419dfd7 100644 --- a/doc/build/changelog/changelog_10.rst +++ b/doc/build/changelog/changelog_10.rst @@ -85,6 +85,15 @@ collection of the mapped table, thereby interfering with the initialization of relationships. + .. change:: + :tags: bug, orm + :tickets: 3781 + :versions: 1.1.4 + + Fixed bug in :meth:`.Session.bulk_save` where an UPDATE would + not function correctly in conjunction with a mapping that + implements a version id counter. + .. changelog:: :version: 1.0.15 :released: September 1, 2016 diff --git a/lib/sqlalchemy/orm/persistence.py b/lib/sqlalchemy/orm/persistence.py index bf51a2a83..2f7acba3a 100644 --- a/lib/sqlalchemy/orm/persistence.py +++ b/lib/sqlalchemy/orm/persistence.py @@ -84,11 +84,16 @@ def _bulk_update(mapper, mappings, session_transaction, cached_connections = _cached_connection_dict(base_mapper) + search_keys = mapper._primary_key_propkeys + if mapper._version_id_prop: + search_keys = set([mapper._version_id_prop.key]).union(search_keys) + def _changed_dict(mapper, state): return dict( (k, v) for k, v in state.dict.items() if k in state.committed_state or k - in mapper._primary_key_propkeys + in search_keys + ) if isstates: diff --git a/test/orm/test_bulk.py b/test/orm/test_bulk.py index 8a8fd004d..cd569fa73 100644 --- a/test/orm/test_bulk.py +++ b/test/orm/test_bulk.py @@ -13,6 +13,57 @@ class BulkTest(testing.AssertsExecutionResults): run_define_tables = 'each' +class BulkInsertUpdateVersionId(BulkTest, fixtures.MappedTest): + @classmethod + def define_tables(cls, metadata): + Table('version_table', metadata, + Column('id', Integer, primary_key=True, + test_needs_autoincrement=True), + Column('version_id', Integer, nullable=False), + Column('value', String(40), nullable=False)) + + @classmethod + def setup_classes(cls): + class Foo(cls.Comparable): + pass + + @classmethod + def setup_mappers(cls): + Foo, version_table = cls.classes.Foo, cls.tables.version_table + + mapper(Foo, version_table, version_id_col=version_table.c.version_id) + + def test_bulk_insert_via_save(self): + Foo = self.classes.Foo + + s = Session() + + s.bulk_save_objects([Foo(value='value')]) + + eq_( + s.query(Foo).all(), + [Foo(version_id=1, value='value')] + ) + + def test_bulk_update_via_save(self): + Foo = self.classes.Foo + + s = Session() + + s.add(Foo(value='value')) + s.commit() + + f1 = s.query(Foo).first() + f1.value = 'new value' + s.bulk_save_objects([f1]) + s.expunge_all() + + eq_( + s.query(Foo).all(), + [Foo(version_id=2, value='new value')] + ) + + class BulkInsertUpdateTest(BulkTest, _fixtures.FixtureTest): @classmethod |