diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-12-22 18:14:31 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-12-22 18:15:30 -0500 |
| commit | 5cc18bb80077e98418b4a8066c0bc628209f3ada (patch) | |
| tree | 1c6cc5c68aa2cb027565f023767b3f52c5b06a49 | |
| parent | b973cbd8939f2cc0e29c668fffd507958c3e455a (diff) | |
| download | sqlalchemy-5cc18bb80077e98418b4a8066c0bc628209f3ada.tar.gz | |
expand out Index if passed to "constraint"
Fixed bug where the PostgreSQL
:paramref:`_postgresql.OnConflictClause.constraint` parameter would accept
an :class:`.Index` object, however would not expand this index out into its
individual index expressions, instead rendering its name in an ON CONFLICT
ON CONSTRAINT clause, which is not accepted by PostgreSQL; the "constraint
name" form only accepts unique or exclude constraint names. The parameter
continues to accept the index but now expands it out into its component
expressions for the render.
Fixes: #9023
Change-Id: I6baf243e26bfe578bf3f193c162dd7a623b6ede9
| -rw-r--r-- | doc/build/changelog/unreleased_14/9023.rst | 12 | ||||
| -rw-r--r-- | lib/sqlalchemy/dialects/postgresql/dml.py | 2 | ||||
| -rw-r--r-- | test/dialect/postgresql/test_on_conflict.py | 39 |
3 files changed, 52 insertions, 1 deletions
diff --git a/doc/build/changelog/unreleased_14/9023.rst b/doc/build/changelog/unreleased_14/9023.rst new file mode 100644 index 000000000..d17a0cc98 --- /dev/null +++ b/doc/build/changelog/unreleased_14/9023.rst @@ -0,0 +1,12 @@ +.. change:: + :tags: bug, postgresql + :tickets: 9023 + + Fixed bug where the PostgreSQL + :paramref:`_postgresql.OnConflictClause.constraint` parameter would accept + an :class:`.Index` object, however would not expand this index out into its + individual index expressions, instead rendering its name in an ON CONFLICT + ON CONSTRAINT clause, which is not accepted by PostgreSQL; the "constraint + name" form only accepts unique or exclude constraint names. The parameter + continues to accept the index but now expands it out into its component + expressions for the render. diff --git a/lib/sqlalchemy/dialects/postgresql/dml.py b/lib/sqlalchemy/dialects/postgresql/dml.py index 645bedf17..27075191d 100644 --- a/lib/sqlalchemy/dialects/postgresql/dml.py +++ b/lib/sqlalchemy/dialects/postgresql/dml.py @@ -213,7 +213,7 @@ class OnConflictClause(ClauseElement): if constraint is not None: if not isinstance(constraint, str) and isinstance( constraint, - (schema.Index, schema.Constraint, ext.ExcludeConstraint), + (schema.Constraint, ext.ExcludeConstraint), ): constraint = getattr(constraint, "name") or constraint diff --git a/test/dialect/postgresql/test_on_conflict.py b/test/dialect/postgresql/test_on_conflict.py index 3cdad78f0..8ef0f158e 100644 --- a/test/dialect/postgresql/test_on_conflict.py +++ b/test/dialect/postgresql/test_on_conflict.py @@ -682,6 +682,45 @@ class OnConflictTest(fixtures.TablesTest): [(1, "name1", "mail2@gmail.com", "unique_name")], ) + def test_on_conflict_do_update_constraint_can_be_index(self, connection): + """test #9023""" + + users = self.tables.users_xtra + + connection.execute( + insert(users), + dict( + id=1, + name="name1", + login_email="mail1@gmail.com", + lets_index_this="unique_name", + ), + ) + + i = insert(users) + i = i.on_conflict_do_update( + constraint=self.unique_partial_index, + set_=dict( + name=i.excluded.name, login_email=i.excluded.login_email + ), + ) + + connection.execute( + i, + [ + dict( + name="name1", + login_email="mail2@gmail.com", + lets_index_this="unique_name", + ) + ], + ) + + eq_( + connection.execute(users.select()).fetchall(), + [(1, "name1", "mail2@gmail.com", "unique_name")], + ) + def test_on_conflict_do_update_no_row_actually_affected(self, connection): users = self.tables.users_xtra |
