From: Jan Katins Date: Mon, 27 Feb 2023 22:05:25 +0000 (+0100) Subject: Also support text X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=68360ce9aa746a85407c5e1e04b8021123d98504;p=thirdparty%2Fsqlalchemy%2Falembic.git Also support text Only works on latest head, but we only check for 2.0 --- diff --git a/alembic/ddl/postgresql.py b/alembic/ddl/postgresql.py index 877338b6..f5f33b7e 100644 --- a/alembic/ddl/postgresql.py +++ b/alembic/ddl/postgresql.py @@ -22,6 +22,7 @@ from sqlalchemy.dialects.postgresql import ExcludeConstraint from sqlalchemy.dialects.postgresql import INTEGER from sqlalchemy.schema import CreateIndex from sqlalchemy.sql.elements import ColumnClause +from sqlalchemy.sql.elements import TextClause from sqlalchemy.types import NULLTYPE from .base import alter_column @@ -667,11 +668,11 @@ def _exclude_constraint( def _render_potential_column( - value: Union[ColumnClause, Column], autogen_context: AutogenContext + value: Union[ColumnClause, Column, TextClause], autogen_context: AutogenContext ) -> str: if isinstance(value, ColumnClause): if value.is_literal: - # Support stuff like literal_column("int8range(from, to)") in ExcludeConstraint + # like literal_column("int8range(from, to)") in ExcludeConstraint template = "%(prefix)sliteral_column(%(name)r)" else: template = "%(prefix)scolumn(%(name)r)" @@ -680,7 +681,12 @@ def _render_potential_column( "prefix": render._sqlalchemy_autogenerate_prefix(autogen_context), "name": value.name, } - + elif isinstance(value, TextClause): + template = "%(prefix)stext(%(text)r)" + return template % { + "prefix": render._sqlalchemy_autogenerate_prefix(autogen_context), + "text": value.text, + } else: return render._render_potential_expr( value, autogen_context, wrap_in_text=False diff --git a/tests/test_postgresql.py b/tests/test_postgresql.py index 8e901c55..25d4c3a1 100644 --- a/tests/test_postgresql.py +++ b/tests/test_postgresql.py @@ -1182,6 +1182,36 @@ class PostgresqlAutogenRenderTest(TestBase): "name='TExclID'))", ) + @config.requirements.sqlalchemy_2 + def test_inline_exclude_constraint_text(self): + # Actually, this only works on sqlalchemy 2.x >= 2023-03-03 due to a bug in sqlalchemy + # See https://github.com/sqlalchemy/alembic/issues/1184 + # and https://github.com/sqlalchemy/sqlalchemy/issues/9401 + + from sqlalchemy.dialects.postgresql import ExcludeConstraint + + autogen_context = self.autogen_context + + m = MetaData() + t = Table( + "TTable", m, Column("id", String()), + ExcludeConstraint( + (text("id + 2"), "="), name="TExclID", using="gist" + ), + ) + + op_obj = ops.CreateTableOp.from_table(t) + + eq_ignore_whitespace( + autogenerate.render_op_text(autogen_context, op_obj), + "op.create_table('TTable',sa.Column('id', sa.String(), " + "nullable=True)," + "postgresql.ExcludeConstraint((sa.text('id + 2'), '='), " + "using='gist', " + "name='TExclID'))", + ) + + def test_json_type(self): eq_ignore_whitespace( autogenerate.render._repr_type(JSON(), self.autogen_context),