From 6741cf359bcb7ad9a48fc50cf64ea024671d7788 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 28 Dec 2011 10:36:07 -0500 Subject: [PATCH] - [bug] Fix autogenerate bug that prevented correct reflection of a foreign-key referenced table in the list of "to remove". [#16] --- CHANGES | 5 +++++ alembic/autogenerate.py | 8 +++++++- tests/test_autogenerate.py | 19 ++++++++++++++++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 68789a2c..6e5073c7 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,11 @@ generated between the two comments if no net migrations were present. +- [bug] Fix autogenerate bug that prevented + correct reflection of a foreign-key + referenced table in the list of "to remove". + [#16] + 0.1.0 ===== - Initial release. Status of features: diff --git a/alembic/autogenerate.py b/alembic/autogenerate.py index 3ddf773c..5c8c6f2b 100644 --- a/alembic/autogenerate.py +++ b/alembic/autogenerate.py @@ -55,14 +55,20 @@ def _produce_net_changes(connection, metadata, diffs, autogen_context): difference(['alembic_version']) metadata_table_names = set(metadata.tables) + _compare_tables(conn_table_names, metadata_table_names, inspector, metadata, diffs, autogen_context) + +def _compare_tables(conn_table_names, metadata_table_names, + inspector, metadata, diffs, autogen_context): for tname in metadata_table_names.difference(conn_table_names): diffs.append(("add_table", metadata.tables[tname])) log.info("Detected added table %r", tname) removal_metadata = schema.MetaData() for tname in conn_table_names.difference(metadata_table_names): + exists = tname in removal_metadata.tables t = schema.Table(tname, removal_metadata) - inspector.reflecttable(t, None) + if not exists: + inspector.reflecttable(t, None) diffs.append(("remove_table", t)) log.info("Detected removed table %r", tname) diff --git a/tests/test_autogenerate.py b/tests/test_autogenerate.py index 6b0308ff..2beed588 100644 --- a/tests/test_autogenerate.py +++ b/tests/test_autogenerate.py @@ -1,6 +1,7 @@ from sqlalchemy import MetaData, Column, Table, Integer, String, Text, \ Numeric, CHAR, ForeignKey, DATETIME, TypeDecorator from sqlalchemy.types import NULLTYPE +from sqlalchemy.engine.reflection import Inspector from alembic import autogenerate, context from unittest import TestCase from tests import staging_env, sqlite_db, clear_staging_env, eq_, \ @@ -31,7 +32,8 @@ def _model_one(): ) Table('extra', m, - Column("x", CHAR) + Column("x", CHAR), + Column('uid', Integer, ForeignKey('user.id')) ) return m @@ -192,6 +194,8 @@ class AutogenerateDiffTest(TestCase): drop_table('item') create_table('extra', sa.Column('x', sa.CHAR(), nullable=True), + sa.Column('uid', sa.INTEGER(), nullable=True), + sa.ForeignKeyConstraint([uid], ['user.id'], ), sa.PrimaryKeyConstraint() ) drop_column('address', 'street') @@ -250,6 +254,19 @@ class AutogenerateDiffTest(TestCase): ) assert not diff + def test_dont_barf_on_already_reflected(self): + diffs = [] + from sqlalchemy.util import OrderedSet + inspector = Inspector.from_engine(self.bind) + autogenerate._compare_tables( + OrderedSet(['extra', 'user']), OrderedSet(), inspector, + MetaData(), diffs, self.autogen_context + ) + eq_( + [(rec[0], rec[1].name) for rec in diffs], + [('remove_table', 'extra'), ('remove_table', u'user')] + ) + class AutogenRenderTest(TestCase): """test individual directives""" -- 2.47.2