from sqlalchemy.util import OrderedSet
from .compare import _compare_tables
from .render import _drop_table, _drop_column, _drop_index, _drop_constraint, \
- _add_table, _add_column, _add_index, _add_constraint, _modify_col
+ _add_table, _add_column, _add_index, _add_constraint, _modify_col, \
+ _add_fk_constraint
from .. import util
log = logging.getLogger(__name__)
"column": (_drop_column, _add_column),
"index": (_drop_index, _add_index),
"constraint": (_drop_constraint, _add_constraint),
+ "fk":(_drop_constraint, _add_fk_constraint)
}
cmd_callables = _commands[cmd_type]
metadata_table.foreign_keys)
fk_models_set = set(fk_models.keys())
for key in (fk_db_set - fk_models_set):
- diffs.append(('drop_key', fk_db[key], conn_table, key))
+ diffs.append(('drop_fk', fk_db[key], conn_table, key))
log.info(("Detected removed foreign key %(fk)r on "
"table %(table)r"), {'fk': fk_db[key],
'table': conn_table})
for key in (fk_models_set - fk_db_set):
- diffs.append(('add_key', fk_models[key], key))
+ diffs.append(('add_fk', fk_models[key], key))
log.info((
"Detected added foreign key for column %(fk)r on table "
"%(table)r"), {'fk': fk_models[key].column.name,
return diffs
-def _get_fk_info_from_db(self, fk):
- return self.FKInfo(tuple(fk['constrained_columns']),
+def _get_fk_info_from_db(fk):
+ return FKInfo(tuple(fk['constrained_columns']),
fk['referred_table'],
tuple(fk['referred_columns']))
-def _get_fk_info_from_model(self, fk):
- return self.FKInfo((fk.parent.name,), fk.column.table.name,
+def _get_fk_info_from_model(fk):
+ return FKInfo((fk.parent.name,), fk.column.table.name,
(fk.column.name,))
\ No newline at end of file
}
-def _add_fk_constraint(constraint, autogen_context):
+def _add_fk_constraint(constraint, fk_info, autogen_context):
raise NotImplementedError()
--- /dev/null
+import sys
+from alembic.testing import TestBase
+
+from sqlalchemy import MetaData, Column, Table, Integer, String, \
+ ForeignKeyConstraint
+from alembic.testing import eq_
+
+py3k = sys.version_info >= (3, )
+
+from .test_autogenerate import AutogenFixtureTest
+
+
+class AutogenerateForeignKeysTest(AutogenFixtureTest, TestBase):
+ __only_on__ = 'sqlite'
+
+ def test_extra_fk(self):
+ m1 = MetaData()
+ m2 = MetaData()
+
+ Table('table', m1,
+ Column('id', Integer, primary_key=True),
+ Column('test', String(10)))
+
+ Table('user', m1,
+ Column('id', Integer, primary_key=True),
+ Column('name', String(50), nullable=False),
+ Column('a1', String(10), server_default="x"),
+ Column('test2', String(10)),
+ ForeignKeyConstraint(['test2'], ['table.test']))
+
+ Table('table', m2,
+ Column('id', Integer, primary_key=True),
+ Column('test', String(10)))
+
+ Table('user', m2,
+ Column('id', Integer, primary_key=True),
+ Column('name', String(50), nullable=False),
+ Column('a1', String(10), server_default="x"),
+ Column('test2', String(10))
+ )
+
+ diffs = self._fixture(m1, m2)
+
+ eq_(diffs[0][0], "drop_fk")
+ eq_(diffs[0][2].name, "user")
+ eq_(diffs[0][3].constrained_columns, ('test2',))
+ eq_(diffs[0][3].referred_table, 'table')
+ eq_(diffs[0][3].referred_columns, ('test',))
+
+ def test_missing_fk(self):
+ m1 = MetaData()
+ m2 = MetaData()
+
+ Table('table', m1,
+ Column('id', Integer, primary_key=True),
+ Column('test', String(10)))
+
+ Table('user', m1,
+ Column('id', Integer, primary_key=True),
+ Column('name', String(50), nullable=False),
+ Column('a1', String(10), server_default="x"),
+ Column('test2', String(10)))
+
+ Table('table', m2,
+ Column('id', Integer, primary_key=True),
+ Column('test', String(10)))
+
+ Table('user', m2,
+ Column('id', Integer, primary_key=True),
+ Column('name', String(50), nullable=False),
+ Column('a1', String(10), server_default="x"),
+ Column('test2', String(10)),
+ ForeignKeyConstraint(['test2'], ['table.test']))
+
+ diffs = self._fixture(m1, m2)
+
+ eq_(diffs[0][0], "add_fk")
+ eq_(diffs[0][1].parent.table.name, "user")
+ eq_(diffs[0][2].constrained_columns, ('test2',))
+ eq_(diffs[0][2].referred_table, 'table')
+ eq_(diffs[0][2].referred_columns, ('test',))
\ No newline at end of file
eq_(repr(diffs[4][0][5]), "NUMERIC(precision=8, scale=2)")
eq_(repr(diffs[4][0][6]), "Numeric(precision=10, scale=2)")
- eq_(diffs[5][0], 'remove_column')
- eq_(diffs[5][3].name, 'pw')
+ eq_(diffs[5][0], 'add_fk')
+ eq_(diffs[5][1].column.name, 'id')
+ eq_(diffs[5][1].parent.table.name, 'order')
+ eq_(diffs[5][2].referred_table, 'user')
+ eq_(diffs[5][2].constrained_columns, ('user_id',))
- eq_(diffs[6][0][0], "modify_default")
- eq_(diffs[6][0][1], None)
- eq_(diffs[6][0][2], "user")
- eq_(diffs[6][0][3], "a1")
- eq_(diffs[6][0][6].arg, "x")
+ eq_(diffs[6][0], 'remove_column')
+ eq_(diffs[6][3].name, 'pw')
- eq_(diffs[7][0][0], 'modify_nullable')
- eq_(diffs[7][0][5], True)
- eq_(diffs[7][0][6], False)
+ eq_(diffs[7][0][0], "modify_default")
+ eq_(diffs[7][0][1], None)
+ eq_(diffs[7][0][2], "user")
+ eq_(diffs[7][0][3], "a1")
+ eq_(diffs[7][0][6].arg, "x")
+
+ eq_(diffs[8][0][0], 'modify_nullable')
+ eq_(diffs[8][0][5], True)
+ eq_(diffs[8][0][6], False)
def test_render_nothing(self):
context = MigrationContext.configure(
eq_(repr(diffs[4][0][5]), "NUMERIC(precision=8, scale=2)")
eq_(repr(diffs[4][0][6]), "Numeric(precision=10, scale=2)")
- eq_(diffs[5][0], 'remove_column')
- eq_(diffs[5][3].name, 'pw')
+ eq_(diffs[5][0], 'add_fk')
+ eq_(diffs[5][1].column.name, 'id')
+ eq_(diffs[5][1].parent.table.name, 'order')
+ eq_(diffs[5][2].referred_table, 'user')
+ eq_(diffs[5][2].constrained_columns, ('user_id',))
- eq_(diffs[6][0][0], "modify_default")
- eq_(diffs[6][0][1], None)
- eq_(diffs[6][0][2], "user")
- eq_(diffs[6][0][3], "a1")
- eq_(diffs[6][0][6].arg, "x")
+ eq_(diffs[6][0], 'remove_column')
+ eq_(diffs[6][3].name, 'pw')
- eq_(diffs[7][0][0], 'modify_nullable')
- eq_(diffs[7][0][5], True)
- eq_(diffs[7][0][6], False)
+ eq_(diffs[7][0][0], "modify_default")
+ eq_(diffs[7][0][1], None)
+ eq_(diffs[7][0][2], "user")
+ eq_(diffs[7][0][3], "a1")
+ eq_(diffs[7][0][6].arg, "x")
+
+ eq_(diffs[8][0][0], 'modify_nullable')
+ eq_(diffs[8][0][5], True)
+ eq_(diffs[8][0][6], False)
def test_compare_metadata_include_object(self):
metadata = self.m2