From: Federico Caselli Date: Wed, 1 Mar 2023 22:22:46 +0000 (+0100) Subject: Fixed issue when copying ExcludeConstraint X-Git-Tag: rel_2_0_5~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7099dd20e90307237240f30d5db0816a08356a5b;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Fixed issue when copying ExcludeConstraint Fixes: #9401 Change-Id: Ie10192348749567110f53ae618fc724f37d1a6a1 --- diff --git a/doc/build/changelog/unreleased_20/9401.rst b/doc/build/changelog/unreleased_20/9401.rst new file mode 100644 index 0000000000..48d88f56bf --- /dev/null +++ b/doc/build/changelog/unreleased_20/9401.rst @@ -0,0 +1,5 @@ +.. change:: + :tags: bug, schema, postgresql + :tickets: 9401 + + Fixed issue when copying ExcludeConstraint. diff --git a/lib/sqlalchemy/dialects/postgresql/ext.py b/lib/sqlalchemy/dialects/postgresql/ext.py index f382af86f3..8c09edddac 100644 --- a/lib/sqlalchemy/dialects/postgresql/ext.py +++ b/lib/sqlalchemy/dialects/postgresql/ext.py @@ -7,7 +7,6 @@ # mypy: ignore-errors from __future__ import annotations -from itertools import zip_longest from typing import Any from typing import TYPE_CHECKING from typing import TypeVar @@ -256,22 +255,20 @@ class ExcludeConstraint(ColumnCollectionConstraint): self._render_exprs = [ ( - expr if isinstance(expr, elements.ClauseElement) else colexpr, + expr if not isinstance(expr, str) else table.c[expr], name, operator, ) - for (expr, name, operator), colexpr in zip_longest( - self._render_exprs, self.columns - ) + for expr, name, operator in (self._render_exprs) ] def _copy(self, target_table=None, **kw): elements = [ ( schema._copy_expression(expr, self.parent, target_table), - self.operators[expr.name], + operator, ) - for expr in self.columns + for expr, _, operator in self._render_exprs ] c = self.__class__( *elements, diff --git a/test/dialect/postgresql/test_compiler.py b/test/dialect/postgresql/test_compiler.py index 2c0dbfccd7..25b02ade9b 100644 --- a/test/dialect/postgresql/test_compiler.py +++ b/test/dialect/postgresql/test_compiler.py @@ -1135,6 +1135,40 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL): "ALTER TABLE testtbl ADD EXCLUDE USING gist (room WITH =)", ) + def test_exclude_constraint_copy_complex(self): + m = MetaData() + tbl = Table("foo", m, Column("x", Integer), Column("y", Integer)) + cons = ExcludeConstraint( + (tbl.c.x, "*"), + (text("x-y"), "%"), + (literal_column("x+y"), "$"), + (tbl.c.x // tbl.c.y, "??"), + (func.power(tbl.c.x, 42), "="), + (func.int8range(column("x"), column("y")), "&&"), + ("y", "^"), + ) + tbl.append_constraint(cons) + expected = ( + "ALTER TABLE {name} ADD EXCLUDE USING gist " + "(x WITH *, x-y WITH %, x+y WITH $, x / y WITH ??, " + "power(x, 42) WITH =, int8range(x, y) WITH &&, y WITH ^)" + ) + self.assert_compile( + schema.AddConstraint(cons), + expected.format(name="foo"), + dialect=postgresql.dialect(), + ) + m2 = MetaData() + tbl2 = tbl.to_metadata(m2, name="bar") + (cons2,) = [ + c for c in tbl2.constraints if isinstance(c, ExcludeConstraint) + ] + self.assert_compile( + schema.AddConstraint(cons2), + expected.format(name="bar"), + dialect=postgresql.dialect(), + ) + def test_exclude_constraint_copy_where_using(self): m = MetaData() tbl = Table("testtbl", m, Column("room", Integer, primary_key=True))