From 2a0441c3b21602ea6bd83aca0877f562c2c64c25 Mon Sep 17 00:00:00 2001 From: Ajaysingh-2003 Date: Mon, 6 Apr 2026 23:44:22 +0530 Subject: [PATCH] Fix rendering of Column objects in dialect kwargs like postgresql_include Fixes: #1258 --- alembic/autogenerate/render.py | 22 +++++++++++++++++++- docs/build/unreleased/1258.rst | 10 +++++++++ tests/test_autogen_render.py | 38 ++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 docs/build/unreleased/1258.rst diff --git a/alembic/autogenerate/render.py b/alembic/autogenerate/render.py index 7f32838d..142deaf9 100644 --- a/alembic/autogenerate/render.py +++ b/alembic/autogenerate/render.py @@ -306,8 +306,28 @@ def _drop_table(autogen_context: AutogenContext, op: ops.DropTableOp) -> str: def _render_dialect_kwargs_items( autogen_context: AutogenContext, dialect_kwargs: _DialectArgView ) -> list[str]: + def _render_kwarg_value(val: Any) -> str: + if isinstance(val, (list, tuple)): + rendered = [ + ( + repr(_ident(getattr(item, "name", None))) + if isinstance(item, sa_schema.Column) + else _render_potential_expr(item, autogen_context) + ) + for item in val + ] + if isinstance(val, tuple): + return "(%s%s)" % ( + ", ".join(rendered), + "," if len(rendered) == 1 else "", + ) + else: + return "[%s]" % ", ".join(rendered) + else: + return _render_potential_expr(val, autogen_context) + return [ - f"{key}={_render_potential_expr(val, autogen_context)}" + f"{key}={_render_kwarg_value(val)}" for key, val in dialect_kwargs.items() ] diff --git a/docs/build/unreleased/1258.rst b/docs/build/unreleased/1258.rst new file mode 100644 index 00000000..ad73a656 --- /dev/null +++ b/docs/build/unreleased/1258.rst @@ -0,0 +1,10 @@ +.. change:: + :tags: bug, autogenerate + :tickets: 1258 + + Fixed rendering of dialect keyword arguments containing + :class:`~sqlalchemy.schema.Column` objects within sequences, such as + ``postgresql_include``. These were previously rendered using ``repr()``, + producing invalid Python in the generated migration scripts. Column + objects within list or tuple values are now correctly rendered as their + string column names. Pull request courtesy Ajay Singh. diff --git a/tests/test_autogen_render.py b/tests/test_autogen_render.py index 0e7899f8..2c466497 100644 --- a/tests/test_autogen_render.py +++ b/tests/test_autogen_render.py @@ -147,6 +147,25 @@ def test_render_add_index_custom_kwarg(self): "['active', 'code'], unique=False, somedialect_foobar='option')", ) + @testing.emits_warning("Can't validate argument ") + def test_render_add_index_dialect_kwarg_with_columns(self): + """test that Column objects in dialect kwargs like + postgresql_include are rendered as column name strings, + not as raw Column repr. + """ + t = self.table() + idx = Index( + "test_active_code_idx", + t.c.active, + somedialect_include=[t.c.code], + ) + op_obj = ops.CreateIndexOp.from_index(idx) + eq_ignore_whitespace( + autogenerate.render_op_text(self.autogen_context, op_obj), + "op.create_index('test_active_code_idx', 'test', " + "['active'], unique=False, somedialect_include=['code'])", + ) + def test_render_add_index_batch(self): """ autogenerate.render._add_index @@ -316,6 +335,25 @@ def test_render_drop_index_custom_kwarg(self): "somedialect_foobar='option')", ) + @testing.emits_warning("Can't validate argument ") + def test_render_drop_index_dialect_kwarg_with_columns(self): + """test that Column objects in dialect kwargs like + postgresql_include are rendered as column name strings + in drop_index, not as raw Column repr. + """ + t = self.table() + idx = Index( + "test_active_code_idx", + t.c.active, + somedialect_include=(t.c.code,), + ) + op_obj = ops.DropIndexOp.from_index(idx) + eq_ignore_whitespace( + autogenerate.render_op_text(self.autogen_context, op_obj), + "op.drop_index('test_active_code_idx', table_name='test', " + "somedialect_include=('code',))", + ) + def test_add_fk_constraint__dialect_kwargs(self): t1 = self.table() t2 = self.table()