diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-04-26 13:30:29 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-04-26 14:59:15 -0400 |
| commit | 87b551c26014c2bf2406ebebb47ee9d3769da9bb (patch) | |
| tree | 5cd1d3384022e6c9e99c1255806a091ec7da2c2a /test/sql | |
| parent | 1443945e61f1f113e46a5044315a91558d4d232a (diff) | |
| download | sqlalchemy-87b551c26014c2bf2406ebebb47ee9d3769da9bb.tar.gz | |
Handle Sequence in _process_multiparam_default_bind
Fixed issue where usage of an explicit :class:`.Sequence` would produce
inconsistent "inline" behavior for an :class:`.Insert` construct that
includes multiple values phrases; the first seq would be inline but
subsequent ones would be "pre-execute", leading to inconsistent sequence
ordering. The sequence expressions are now fully inline.
Fixes: #6361
Change-Id: Ie16794ec0e19979a7e6c8d1bef5716a9fc199889
Diffstat (limited to 'test/sql')
| -rw-r--r-- | test/sql/test_insert.py | 69 | ||||
| -rw-r--r-- | test/sql/test_sequences.py | 38 |
2 files changed, 107 insertions, 0 deletions
diff --git a/test/sql/test_insert.py b/test/sql/test_insert.py index 95a8d02a2..6c2a5d955 100644 --- a/test/sql/test_insert.py +++ b/test/sql/test_insert.py @@ -384,6 +384,75 @@ class InsertTest(_InsertTestBase, fixtures.TablesTest, AssertsCompiledSQL): dialect=postgresql.dialect(), ) + def test_insert_seq_pk_multi_values(self): + """test #6361""" + + m = MetaData() + + t1 = Table( + "t", + m, + Column("id", Integer, Sequence("id_seq"), primary_key=True), + Column("data", String), + ) + + stmt = t1.insert().values( + [{"data": "d1"}, {"data": "d2"}, {"data": "d3"}] + ) + + self.assert_compile( + stmt, + "INSERT INTO t (id, data) VALUES (nextval('id_seq'), " + "%(data_m0)s), (nextval('id_seq'), %(data_m1)s), " + "(nextval('id_seq'), %(data_m2)s)", + dialect=postgresql.dialect(), + ) + + def test_insert_seq_non_pk_multi_values(self): + """test #6361""" + + m = MetaData() + + t1 = Table( + "t", + m, + Column("id", Integer, primary_key=True), + Column("counter", Sequence("counter_seq")), + Column("data", String), + ) + + stmt = t1.insert().values( + [{"data": "d1"}, {"data": "d2"}, {"data": "d3"}] + ) + + self.assert_compile( + stmt, + "INSERT INTO t (counter, data) VALUES (nextval('counter_seq'), " + "%(data_m0)s), (nextval('counter_seq'), %(data_m1)s), " + "(nextval('counter_seq'), %(data_m2)s)", + dialect=postgresql.dialect(), + ) + + def test_insert_seq_pk_multi_values_seq_not_supported(self): + m = MetaData() + + t1 = Table( + "t", + m, + Column("id", Integer, Sequence("id_seq"), primary_key=True), + Column("data", String), + ) + + stmt = t1.insert().values( + [{"data": "d1"}, {"data": "d2"}, {"data": "d3"}] + ) + + self.assert_compile( + stmt, + "INSERT INTO t (data) VALUES (?), (?), (?)", + dialect=sqlite.dialect(), + ) + def test_insert_from_select_cte_one(self): table1 = self.tables.mytable diff --git a/test/sql/test_sequences.py b/test/sql/test_sequences.py index 3b25ba2ad..d1d46afa3 100644 --- a/test/sql/test_sequences.py +++ b/test/sql/test_sequences.py @@ -204,6 +204,44 @@ class SequenceExecTest(fixtures.TestBase): else: eq_(r.inserted_primary_key, (None,)) + @testing.combinations( + ("implicit_returning",), + ("no_implicit_returning",), + ("explicit_returning", testing.requires.returning), + argnames="returning", + ) + @testing.requires.multivalues_inserts + def test_seq_multivalues_inline(self, metadata, testing_engine, returning): + t1 = Table( + "t", + metadata, + Column("x", Integer, Sequence("my_seq"), primary_key=True), + Column("data", String(50)), + ) + + e = engines.testing_engine( + options={ + "implicit_returning": returning != "no_implicit_returning" + } + ) + metadata.create_all(e) + with e.begin() as conn: + + stmt = t1.insert().values( + [{"data": "d1"}, {"data": "d2"}, {"data": "d3"}] + ) + if returning == "explicit_returning": + stmt = stmt.returning(t1.c.x) + + r = conn.execute(stmt) + if returning == "explicit_returning": + eq_(r.all(), [(1,), (2,), (3,)]) + + eq_( + conn.execute(t1.select().order_by(t1.c.x)).all(), + [(1, "d1"), (2, "d2"), (3, "d3")], + ) + @testing.requires.returning @testing.provide_metadata def test_inserted_pk_implicit_returning(self): |
