summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/orm/test_cycles.py18
-rw-r--r--test/sql/test_constraints.py207
-rw-r--r--test/sql/test_ddlemit.py67
3 files changed, 256 insertions, 36 deletions
diff --git a/test/orm/test_cycles.py b/test/orm/test_cycles.py
index 8e086ff88..fc7059dcb 100644
--- a/test/orm/test_cycles.py
+++ b/test/orm/test_cycles.py
@@ -284,7 +284,7 @@ class InheritTestTwo(fixtures.MappedTest):
Table('c', metadata,
Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
Column('aid', Integer,
- ForeignKey('a.id', use_alter=True, name="foo")))
+ ForeignKey('a.id', name="foo")))
@classmethod
def setup_classes(cls):
@@ -334,7 +334,7 @@ class BiDirectionalManyToOneTest(fixtures.MappedTest):
Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
Column('data', String(30)),
Column('t1id', Integer,
- ForeignKey('t1.id', use_alter=True, name="foo_fk")))
+ ForeignKey('t1.id', name="foo_fk")))
Table('t3', metadata,
Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
Column('data', String(30)),
@@ -436,7 +436,7 @@ class BiDirectionalOneToManyTest(fixtures.MappedTest):
Table('t2', metadata,
Column('c1', Integer, primary_key=True, test_needs_autoincrement=True),
Column('c2', Integer,
- ForeignKey('t1.c1', use_alter=True, name='t1c1_fk')))
+ ForeignKey('t1.c1', name='t1c1_fk')))
@classmethod
def setup_classes(cls):
@@ -491,7 +491,7 @@ class BiDirectionalOneToManyTest2(fixtures.MappedTest):
Table('t2', metadata,
Column('c1', Integer, primary_key=True, test_needs_autoincrement=True),
Column('c2', Integer,
- ForeignKey('t1.c1', use_alter=True, name='t1c1_fq')),
+ ForeignKey('t1.c1', name='t1c1_fq')),
test_needs_autoincrement=True)
Table('t1_data', metadata,
@@ -572,7 +572,7 @@ class OneToManyManyToOneTest(fixtures.MappedTest):
Table('ball', metadata,
Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
Column('person_id', Integer,
- ForeignKey('person.id', use_alter=True, name='fk_person_id')),
+ ForeignKey('person.id', name='fk_person_id')),
Column('data', String(30)))
Table('person', metadata,
@@ -1024,7 +1024,7 @@ class SelfReferentialPostUpdateTest3(fixtures.MappedTest):
test_needs_autoincrement=True),
Column('name', String(50), nullable=False),
Column('child_id', Integer,
- ForeignKey('child.id', use_alter=True, name='c1'), nullable=True))
+ ForeignKey('child.id', name='c1'), nullable=True))
Table('child', metadata,
Column('id', Integer, primary_key=True,
@@ -1094,11 +1094,11 @@ class PostUpdateBatchingTest(fixtures.MappedTest):
test_needs_autoincrement=True),
Column('name', String(50), nullable=False),
Column('c1_id', Integer,
- ForeignKey('child1.id', use_alter=True, name='c1'), nullable=True),
+ ForeignKey('child1.id', name='c1'), nullable=True),
Column('c2_id', Integer,
- ForeignKey('child2.id', use_alter=True, name='c2'), nullable=True),
+ ForeignKey('child2.id', name='c2'), nullable=True),
Column('c3_id', Integer,
- ForeignKey('child3.id', use_alter=True, name='c3'), nullable=True)
+ ForeignKey('child3.id', name='c3'), nullable=True)
)
Table('child1', metadata,
diff --git a/test/sql/test_constraints.py b/test/sql/test_constraints.py
index c0b5806ac..604b5efeb 100644
--- a/test/sql/test_constraints.py
+++ b/test/sql/test_constraints.py
@@ -58,8 +58,77 @@ class ConstraintGenTest(fixtures.TestBase, AssertsExecutionResults):
)
)
+ @testing.force_drop_names('a', 'b')
+ def test_fk_cant_drop_cycled_unnamed(self):
+ metadata = MetaData()
+
+ Table("a", metadata,
+ Column('id', Integer, primary_key=True),
+ Column('bid', Integer),
+ ForeignKeyConstraint(["bid"], ["b.id"])
+ )
+ Table(
+ "b", metadata,
+ Column('id', Integer, primary_key=True),
+ Column("aid", Integer),
+ ForeignKeyConstraint(["aid"], ["a.id"]))
+ metadata.create_all(testing.db)
+ if testing.db.dialect.supports_alter:
+ assert_raises_message(
+ exc.CircularDependencyError,
+ "Can't sort tables for DROP; an unresolvable foreign key "
+ "dependency exists between tables: a, b. Please ensure "
+ "that the ForeignKey and ForeignKeyConstraint objects "
+ "involved in the cycle have names so that they can be "
+ "dropped using DROP CONSTRAINT.",
+ metadata.drop_all, testing.db
+ )
+ else:
+
+ with self.sql_execution_asserter() as asserter:
+ metadata.drop_all(testing.db, checkfirst=False)
+
+ asserter.assert_(
+ AllOf(
+ CompiledSQL("DROP TABLE a"),
+ CompiledSQL("DROP TABLE b")
+ )
+ )
+
+ @testing.provide_metadata
+ def test_fk_table_auto_alter_constraint_create(self):
+ metadata = self.metadata
+
+ Table("a", metadata,
+ Column('id', Integer, primary_key=True),
+ Column('bid', Integer),
+ ForeignKeyConstraint(["bid"], ["b.id"])
+ )
+ Table(
+ "b", metadata,
+ Column('id', Integer, primary_key=True),
+ Column("aid", Integer),
+ ForeignKeyConstraint(["aid"], ["a.id"], name="bfk"))
+ self._assert_cyclic_constraint(metadata, auto=True)
+
+ @testing.provide_metadata
+ def test_fk_column_auto_alter_constraint_create(self):
+ metadata = self.metadata
+
+ Table("a", metadata,
+ Column('id', Integer, primary_key=True),
+ Column('bid', Integer, ForeignKey("b.id")),
+ )
+ Table("b", metadata,
+ Column('id', Integer, primary_key=True),
+ Column("aid", Integer,
+ ForeignKey("a.id", name="bfk")
+ ),
+ )
+ self._assert_cyclic_constraint(metadata, auto=True)
+
@testing.provide_metadata
- def test_cyclic_fk_table_constraint_create(self):
+ def test_fk_table_use_alter_constraint_create(self):
metadata = self.metadata
Table("a", metadata,
@@ -75,7 +144,7 @@ class ConstraintGenTest(fixtures.TestBase, AssertsExecutionResults):
self._assert_cyclic_constraint(metadata)
@testing.provide_metadata
- def test_cyclic_fk_column_constraint_create(self):
+ def test_fk_column_use_alter_constraint_create(self):
metadata = self.metadata
Table("a", metadata,
@@ -90,45 +159,104 @@ class ConstraintGenTest(fixtures.TestBase, AssertsExecutionResults):
)
self._assert_cyclic_constraint(metadata)
- def _assert_cyclic_constraint(self, metadata):
- assertions = [
- CompiledSQL('CREATE TABLE b ('
+ def _assert_cyclic_constraint(self, metadata, auto=False):
+ table_assertions = []
+ if auto:
+ if testing.db.dialect.supports_alter:
+ table_assertions.append(
+ CompiledSQL('CREATE TABLE b ('
+ 'id INTEGER NOT NULL, '
+ 'aid INTEGER, '
+ 'PRIMARY KEY (id)'
+ ')'
+ )
+ )
+ else:
+ table_assertions.append(
+ CompiledSQL(
+ 'CREATE TABLE b ('
'id INTEGER NOT NULL, '
'aid INTEGER, '
+ 'PRIMARY KEY (id), '
+ 'CONSTRAINT bfk FOREIGN KEY(aid) REFERENCES a (id)'
+ ')'
+ )
+ )
+
+ if testing.db.dialect.supports_alter:
+ table_assertions.append(
+ CompiledSQL(
+ 'CREATE TABLE a ('
+ 'id INTEGER NOT NULL, '
+ 'bid INTEGER, '
'PRIMARY KEY (id)'
')'
- ),
- CompiledSQL('CREATE TABLE a ('
+ )
+ )
+ else:
+ table_assertions.append(
+ CompiledSQL(
+ 'CREATE TABLE a ('
'id INTEGER NOT NULL, '
'bid INTEGER, '
'PRIMARY KEY (id), '
'FOREIGN KEY(bid) REFERENCES b (id)'
')'
- ),
- ]
+ )
+ )
+ else:
+ table_assertions.append(
+ CompiledSQL('CREATE TABLE b ('
+ 'id INTEGER NOT NULL, '
+ 'aid INTEGER, '
+ 'PRIMARY KEY (id)'
+ ')'
+ )
+ )
+ table_assertions.append(
+ CompiledSQL(
+ 'CREATE TABLE a ('
+ 'id INTEGER NOT NULL, '
+ 'bid INTEGER, '
+ 'PRIMARY KEY (id), '
+ 'FOREIGN KEY(bid) REFERENCES b (id)'
+ ')'
+ )
+ )
+
+ assertions = [AllOf(*table_assertions)]
if testing.db.dialect.supports_alter:
- assertions.append(
+ fk_assertions = []
+ fk_assertions.append(
CompiledSQL('ALTER TABLE b ADD CONSTRAINT bfk '
'FOREIGN KEY(aid) REFERENCES a (id)')
)
- self.assert_sql_execution(
- testing.db,
- lambda: metadata.create_all(checkfirst=False),
- *assertions
- )
+ if auto:
+ fk_assertions.append(
+ CompiledSQL('ALTER TABLE a ADD '
+ 'FOREIGN KEY(bid) REFERENCES b (id)')
+ )
+ assertions.append(AllOf(*fk_assertions))
+
+ with self.sql_execution_asserter() as asserter:
+ metadata.create_all(checkfirst=False)
+ asserter.assert_(*assertions)
- assertions = []
if testing.db.dialect.supports_alter:
- assertions.append(CompiledSQL('ALTER TABLE b DROP CONSTRAINT bfk'))
- assertions.extend([
- CompiledSQL("DROP TABLE a"),
- CompiledSQL("DROP TABLE b"),
- ])
- self.assert_sql_execution(
- testing.db,
- lambda: metadata.drop_all(checkfirst=False),
- *assertions
- )
+ assertions = [
+ CompiledSQL('ALTER TABLE b DROP CONSTRAINT bfk'),
+ CompiledSQL("DROP TABLE a"),
+ CompiledSQL("DROP TABLE b")
+ ]
+ else:
+ assertions = [AllOf(
+ CompiledSQL("DROP TABLE a"),
+ CompiledSQL("DROP TABLE b")
+ )]
+
+ with self.sql_execution_asserter() as asserter:
+ metadata.drop_all(checkfirst=False),
+ asserter.assert_(*assertions)
@testing.requires.check_constraints
@testing.provide_metadata
@@ -542,6 +670,33 @@ class ConstraintCompilationTest(fixtures.TestBase, AssertsCompiledSQL):
"REFERENCES tbl (a) MATCH SIMPLE"
)
+ def test_create_table_omit_fks(self):
+ fkcs = [
+ ForeignKeyConstraint(['a'], ['remote.id'], name='foo'),
+ ForeignKeyConstraint(['b'], ['remote.id'], name='bar'),
+ ForeignKeyConstraint(['c'], ['remote.id'], name='bat'),
+ ]
+ m = MetaData()
+ t = Table(
+ 't', m,
+ Column('a', Integer),
+ Column('b', Integer),
+ Column('c', Integer),
+ *fkcs
+ )
+ Table('remote', m, Column('id', Integer, primary_key=True))
+
+ self.assert_compile(
+ schema.CreateTable(t, include_foreign_key_constraints=[]),
+ "CREATE TABLE t (a INTEGER, b INTEGER, c INTEGER)"
+ )
+ self.assert_compile(
+ schema.CreateTable(t, include_foreign_key_constraints=fkcs[0:2]),
+ "CREATE TABLE t (a INTEGER, b INTEGER, c INTEGER, "
+ "CONSTRAINT foo FOREIGN KEY(a) REFERENCES remote (id), "
+ "CONSTRAINT bar FOREIGN KEY(b) REFERENCES remote (id))"
+ )
+
def test_deferrable_unique(self):
factory = lambda **kw: UniqueConstraint('b', **kw)
self._test_deferrable(factory)
diff --git a/test/sql/test_ddlemit.py b/test/sql/test_ddlemit.py
index 825f8228b..e191beed3 100644
--- a/test/sql/test_ddlemit.py
+++ b/test/sql/test_ddlemit.py
@@ -1,6 +1,6 @@
from sqlalchemy.testing import fixtures
from sqlalchemy.sql.ddl import SchemaGenerator, SchemaDropper
-from sqlalchemy import MetaData, Table, Column, Integer, Sequence
+from sqlalchemy import MetaData, Table, Column, Integer, Sequence, ForeignKey
from sqlalchemy import schema
from sqlalchemy.testing.mock import Mock
@@ -42,6 +42,31 @@ class EmitDDLTest(fixtures.TestBase):
for i in range(1, 6)
)
+ def _use_alter_fixture_one(self):
+ m = MetaData()
+
+ t1 = Table(
+ 't1', m, Column('id', Integer, primary_key=True),
+ Column('t2id', Integer, ForeignKey('t2.id'))
+ )
+ t2 = Table(
+ 't2', m, Column('id', Integer, primary_key=True),
+ Column('t1id', Integer, ForeignKey('t1.id'))
+ )
+ return m, t1, t2
+
+ def _fk_fixture_one(self):
+ m = MetaData()
+
+ t1 = Table(
+ 't1', m, Column('id', Integer, primary_key=True),
+ Column('t2id', Integer, ForeignKey('t2.id'))
+ )
+ t2 = Table(
+ 't2', m, Column('id', Integer, primary_key=True),
+ )
+ return m, t1, t2
+
def _table_seq_fixture(self):
m = MetaData()
@@ -172,6 +197,32 @@ class EmitDDLTest(fixtures.TestBase):
self._assert_drop_tables([t1, t2, t3, t4, t5], generator, m)
+ def test_create_metadata_auto_alter_fk(self):
+ m, t1, t2 = self._use_alter_fixture_one()
+ generator = self._mock_create_fixture(
+ False, [t1, t2]
+ )
+ self._assert_create_w_alter(
+ [t1, t2] +
+ list(t1.foreign_key_constraints) +
+ list(t2.foreign_key_constraints),
+ generator,
+ m
+ )
+
+ def test_create_metadata_inline_fk(self):
+ m, t1, t2 = self._fk_fixture_one()
+ generator = self._mock_create_fixture(
+ False, [t1, t2]
+ )
+ self._assert_create_w_alter(
+ [t1, t2] +
+ list(t1.foreign_key_constraints) +
+ list(t2.foreign_key_constraints),
+ generator,
+ m
+ )
+
def _assert_create_tables(self, elements, generator, argument):
self._assert_ddl(schema.CreateTable, elements, generator, argument)
@@ -188,6 +239,16 @@ class EmitDDLTest(fixtures.TestBase):
(schema.DropTable, schema.DropSequence),
elements, generator, argument)
+ def _assert_create_w_alter(self, elements, generator, argument):
+ self._assert_ddl(
+ (schema.CreateTable, schema.CreateSequence, schema.AddConstraint),
+ elements, generator, argument)
+
+ def _assert_drop_w_alter(self, elements, generator, argument):
+ self._assert_ddl(
+ (schema.DropTable, schema.DropSequence, schema.DropConstraint),
+ elements, generator, argument)
+
def _assert_ddl(self, ddl_cls, elements, generator, argument):
generator.traverse_single(argument)
for call_ in generator.connection.execute.mock_calls:
@@ -196,4 +257,8 @@ class EmitDDLTest(fixtures.TestBase):
assert c.element in elements, "element %r was not expected"\
% c.element
elements.remove(c.element)
+ if getattr(c, 'include_foreign_key_constraints', None) is not None:
+ elements[:] = [
+ e for e in elements
+ if e not in set(c.include_foreign_key_constraints)]
assert not elements, "elements remain in list: %r" % elements