From: Mike Bayer Date: Tue, 19 May 2015 00:21:49 +0000 (-0400) Subject: - Fixed bug where foreign key options including "onupdate", X-Git-Tag: rel_0_7_7~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=29b301a7ec46b871dced5580293fa8f5f8d4e899;p=thirdparty%2Fsqlalchemy%2Falembic.git - Fixed bug where foreign key options including "onupdate", "ondelete" would not render within the ``op.create_foreign_key()`` directive, even though they render within a full ``ForeignKeyConstraint`` directive. fixes #298 --- diff --git a/alembic/__init__.py b/alembic/__init__.py index 1e29b578..f4294417 100644 --- a/alembic/__init__.py +++ b/alembic/__init__.py @@ -1,6 +1,6 @@ from os import path -__version__ = '0.7.6' +__version__ = '0.7.7' package_dir = path.abspath(path.dirname(__file__)) diff --git a/alembic/autogenerate/render.py b/alembic/autogenerate/render.py index 13830cfe..50076529 100644 --- a/alembic/autogenerate/render.py +++ b/alembic/autogenerate/render.py @@ -263,10 +263,10 @@ def _add_fk_constraint(constraint, autogen_context): "%s=%r" % ('referent_schema', target_schema) ) - if constraint.deferrable: - args.append("%s=%r" % ("deferrable", str(constraint.deferrable))) - if constraint.initially: - args.append("%s=%r" % ("initially", str(constraint.initially))) + opts = [] + _populate_render_fk_opts(constraint, opts) + args.extend(("%s=%s" % (k, v) for (k, v) in opts)) + return "%(prefix)screate_foreign_key(%(args)s)" % { 'prefix': _alembic_autogenerate_prefix(autogen_context), 'args': ", ".join(args) @@ -562,15 +562,8 @@ def _fk_colspec(fk, metadata_schema): return colspec -def _render_foreign_key(constraint, autogen_context): - rendered = _user_defined_render("foreign_key", constraint, autogen_context) - if rendered is not False: - return rendered +def _populate_render_fk_opts(constraint, opts): - opts = [] - if constraint.name: - opts.append(("name", repr( - _render_gen_name(autogen_context, constraint.name)))) if constraint.onupdate: opts.append(("onupdate", repr(constraint.onupdate))) if constraint.ondelete: @@ -582,6 +575,19 @@ def _render_foreign_key(constraint, autogen_context): if constraint.use_alter: opts.append(("use_alter", repr(constraint.use_alter))) + +def _render_foreign_key(constraint, autogen_context): + rendered = _user_defined_render("foreign_key", constraint, autogen_context) + if rendered is not False: + return rendered + + opts = [] + if constraint.name: + opts.append(("name", repr( + _render_gen_name(autogen_context, constraint.name)))) + + _populate_render_fk_opts(constraint, opts) + apply_metadata_schema = constraint.parent.metadata.schema return "%(prefix)sForeignKeyConstraint([%(cols)s], "\ "[%(refcols)s], %(args)s)" % { diff --git a/docs/build/changelog.rst b/docs/build/changelog.rst index 81c659d6..e11713a1 100644 --- a/docs/build/changelog.rst +++ b/docs/build/changelog.rst @@ -3,6 +3,18 @@ Changelog ========== +.. changelog:: + :version: 0.7.7 + + .. change:: + :tags: bug, autogenerate + :tickets: 298 + + Fixed bug where foreign key options including "onupdate", + "ondelete" would not render within the ``op.create_foreign_key()`` + directive, even though they render within a full + ``ForeignKeyConstraint`` directive. + .. changelog:: :version: 0.7.6 :released: May 5, 2015 diff --git a/tests/test_autogen_render.py b/tests/test_autogen_render.py index 8d08f666..52f36018 100644 --- a/tests/test_autogen_render.py +++ b/tests/test_autogen_render.py @@ -269,6 +269,81 @@ unique=False, """ "op.create_foreign_key('fk_a_id', 'b', 'a', ['a_id'], ['id'])" ) + def test_add_fk_constraint_kwarg(self): + m = MetaData() + t1 = Table('t', m, Column('c', Integer)) + t2 = Table('t2', m, Column('c_rem', Integer)) + + fk = ForeignKeyConstraint([t1.c.c], [t2.c.c_rem], onupdate="CASCADE") + if not util.sqla_08: + t1.append_constraint(fk) + + # SQLA 0.9 generates a u'' here for remote cols while 0.8 does not, + # so just whack out "'u" here from the generated + + eq_ignore_whitespace( + re.sub( + r"u'", "'", + autogenerate.render._add_fk_constraint( + fk, self.autogen_context)), + "op.create_foreign_key(None, 't', 't2', ['c'], ['c_rem'], " + "onupdate='CASCADE')" + ) + + fk = ForeignKeyConstraint([t1.c.c], [t2.c.c_rem], ondelete="CASCADE") + if not util.sqla_08: + t1.append_constraint(fk) + + eq_ignore_whitespace( + re.sub( + r"u'", "'", + autogenerate.render._add_fk_constraint( + fk, self.autogen_context)), + "op.create_foreign_key(None, 't', 't2', ['c'], ['c_rem'], " + "ondelete='CASCADE')" + ) + + fk = ForeignKeyConstraint([t1.c.c], [t2.c.c_rem], deferrable=True) + if not util.sqla_08: + t1.append_constraint(fk) + eq_ignore_whitespace( + re.sub( + r"u'", "'", + autogenerate.render._add_fk_constraint( + fk, self.autogen_context), + ), + "op.create_foreign_key(None, 't', 't2', ['c'], ['c_rem'], " + "deferrable=True)" + ) + + fk = ForeignKeyConstraint([t1.c.c], [t2.c.c_rem], initially="XYZ") + if not util.sqla_08: + t1.append_constraint(fk) + eq_ignore_whitespace( + re.sub( + r"u'", "'", + autogenerate.render._add_fk_constraint( + fk, self.autogen_context) + ), + "op.create_foreign_key(None, 't', 't2', ['c'], ['c_rem'], " + "initially='XYZ')" + ) + + fk = ForeignKeyConstraint( + [t1.c.c], [t2.c.c_rem], + initially="XYZ", ondelete="CASCADE", deferrable=True) + if not util.sqla_08: + t1.append_constraint(fk) + eq_ignore_whitespace( + re.sub( + r"u'", "'", + autogenerate.render._add_fk_constraint( + fk, self.autogen_context) + ), + "op.create_foreign_key(None, 't', 't2', ['c'], ['c_rem'], " + "ondelete='CASCADE', initially='XYZ', deferrable=True)" + ) + def test_add_fk_constraint_inline_colkeys(self): m = MetaData() Table('a', m, Column('id', Integer, key='aid', primary_key=True))