summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorijl <uijllji@gmail.com>2013-10-15 17:06:42 -0400
committerijl <uijllji@gmail.com>2013-10-15 17:06:42 -0400
commit98e791836c51fd0a9452141047b539af5f0f95bd (patch)
tree6f2319238dc3dbc376e373218604dfb60710b426
parent92534dc8f30d173deaa1221a6872fd9b7ceae325 (diff)
downloadsqlalchemy-pr/36.tar.gz
#2841: MySQL doesn't support MATCH, INITIALLY, or DEFERREDpr/36
-rw-r--r--lib/sqlalchemy/dialects/mysql/base.py14
-rw-r--r--test/engine/test_reflection.py29
2 files changed, 42 insertions, 1 deletions
diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py
index d0f654fe2..60519b798 100644
--- a/lib/sqlalchemy/dialects/mysql/base.py
+++ b/lib/sqlalchemy/dialects/mysql/base.py
@@ -1451,6 +1451,20 @@ class MySQLCompiler(compiler.SQLCompiler):
class MySQLDDLCompiler(compiler.DDLCompiler):
def create_table_constraints(self, table):
"""Get table constraints."""
+
+ # For foreign keys, MySQL silently fails or drops other FK attributes
+ # if MATCH, DEFERRABLE, or INITIALLY are defined. So let's raise an
+ # error here.
+ # https://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html
+ for attr in ('match', 'deferrable', 'initially'):
+ for fk in table.foreign_keys:
+ if getattr(fk, attr) is not None:
+ raise exc.CompileError(
+ "MySQL does not support specifying MATCH, DEFERRABLE, "
+ "or INITIALLY on foreign keys, but a foreign key on "
+ "table '%s' defines at least one." % table.name
+ )
+
constraint_string = super(
MySQLDDLCompiler, self).create_table_constraints(table)
diff --git a/test/engine/test_reflection.py b/test/engine/test_reflection.py
index 21c050915..ec16fe004 100644
--- a/test/engine/test_reflection.py
+++ b/test/engine/test_reflection.py
@@ -624,7 +624,7 @@ class ReflectionTest(fixtures.TestBase, ComparesTables):
finally:
testing.db.execute("drop table book")
- def test_fk_error(self):
+ def test_fk_table_error(self):
metadata = MetaData(testing.db)
Table('slots', metadata,
Column('slot_id', sa.Integer, primary_key=True),
@@ -638,6 +638,33 @@ class ReflectionTest(fixtures.TestBase, ComparesTables):
"a foreign key to target column 'pkg_id'",
metadata.create_all)
+ @testing.only_on('mysql')
+ def test_fk_attribute_error(self):
+ """
+ MySQL FKs cannot handle certain attributes... throw a CompileError
+ """
+ meta = MetaData(testing.db)
+ Table('users', meta,
+ Column('id', sa.Integer, primary_key=True),
+ Column('name', sa.String(30)),
+ test_needs_fk=True)
+ Table('addresses', meta,
+ Column('id', sa.Integer, primary_key=True),
+ Column('user_id', sa.Integer, sa.ForeignKey(
+ 'users.id',
+ name = 'addresses_user_id_fkey',
+ match = 'FULL',
+ onupdate='CASCADE',
+ ondelete='CASCADE'
+ )),
+ test_needs_fk=True)
+
+ assert_raises_message(sa.exc.CompileError,
+ "MySQL does not support specifying MATCH, DEFERRABLE, or "
+ "INITIALLY on foreign keys, but a foreign key on table "
+ "'addresses' defines at least one.",
+ meta.create_all)
+
def test_composite_pks(self):
"""test reflection of a composite primary key"""