]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
- [bug] Added "type" argument to op.drop_constraint(),
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 1 May 2012 15:19:54 +0000 (11:19 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 1 May 2012 15:19:54 +0000 (11:19 -0400)
  and implemented full constraint drop support for
  MySQL.  CHECK and undefined raise an error.
  MySQL needs the constraint type
  in order to emit a DROP CONSTRAINT. #44

CHANGES
alembic/__init__.py
alembic/ddl/mysql.py
alembic/operations.py
tests/test_mysql.py

diff --git a/CHANGES b/CHANGES
index 40a57654134dee7436e647a5eb58c587ff85839b..4a20a5e3a3a260a46158ada44575c6e91cf65721 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,11 @@
+0.3.3
+=====
+- [bug] Added "type" argument to op.drop_constraint(),
+  and implemented full constraint drop support for
+  MySQL.  CHECK and undefined raise an error.  
+  MySQL needs the constraint type
+  in order to emit a DROP CONSTRAINT. #44
+
 0.3.2
 =====
 - [feature] Basic support for Oracle added, 
index 259782c943bff1cb6af24b9fcd78cc9eb1cb62ac..d75fb222f922b39068cf6d583a2e14ebb18ea462 100644 (file)
@@ -1,6 +1,6 @@
 from os import path
 
-__version__ = '0.3.2'
+__version__ = '0.3.3'
 
 package_dir = path.abspath(path.dirname(__file__))
 
index 00cf7ab5d86ad6f4bbbcea2ac6b1c9c3b45a7a80..f5afc22d75d648bdbfaddd10b5972387732fd223 100644 (file)
@@ -4,6 +4,7 @@ from sqlalchemy.ext.compiler import compiles
 from alembic.ddl.base import alter_table
 from alembic import util
 from sqlalchemy import types as sqltypes
+from sqlalchemy import schema
 
 class MySQLImpl(DefaultImpl):
     __dialect__ = 'mysql'
@@ -85,4 +86,22 @@ def _mysql_colspec(compiler, name, nullable, server_default, type_):
 
     return spec
 
+@compiles(schema.DropConstraint, "mysql")
+def _mysql_drop_constraint(element, compiler, **kw):
+    """Redefine SQLAlchemy's drop constraint to 
+    raise errors for invalid constraint type."""
+
+    constraint = element.element
+    if isinstance(constraint, (schema.ForeignKeyConstraint,
+                                schema.PrimaryKeyConstraint,
+                                schema.UniqueConstraint)
+                                ):
+        return compiler.visit_drop_constraint(element, **kw)
+    elif isinstance(constraint, schema.CheckConstraint):
+        raise NotImplementedError(
+                "MySQL does not support CHECK constraints.")
+    else:
+        raise NotImplementedError(
+                "No generic 'DROP CONSTRAINT' in MySQL - "
+                "please specify constraint type")
 
index 7787f77a24fc8e087fa3b602bee0f5f4d0cdf234..9d4b7ef0cdd7209bf696df4eba8610805a18c8c6 100644 (file)
@@ -529,10 +529,30 @@ class Operations(object):
         # 0.7.6 and further raises on Index with no columns
         self.impl.drop_index(self._index(name, tablename, ['x']))
 
-    def drop_constraint(self, name, tablename):
-        """Drop a constraint of the given name"""
+    def drop_constraint(self, name, tablename, type=None):
+        """Drop a constraint of the given name, typically via DROP CONSTRAINT.
+        
+        :param name: name of the constraint.
+        :param tablename: tablename.
+        :param type: optional, required on MySQL.  can be 
+        'foreignkey', 'unique', or 'check'
+
+        """
         t = self._table(tablename)
-        const = schema.Constraint(name=name)
+        types = {
+            'foreignkey':lambda name:schema.ForeignKeyConstraint(
+                                [], [], name=name),
+            'unique':schema.UniqueConstraint,
+            'check':lambda name:schema.CheckConstraint("", name=name),
+            None:schema.Constraint
+        }
+        try:
+            const = types[type]
+        except KeyError:
+            raise TypeError("'type' can be one of %s" % 
+                        ", ".join(sorted(repr(x) for x in types))) 
+
+        const = const(name=name)
         t.append_constraint(const)
         self.impl.drop_constraint(const)
 
index 499dec7ca51b9cdb4233a7a5eff1cf7f99513806..4c4a357d0329087e66fb9032b2163341e226084a 100644 (file)
@@ -40,3 +40,42 @@ def test_col_alter_type_required():
         "All MySQL ALTER COLUMN operations require the existing type.",
         op.alter_column, 't1', 'c1', nullable=False, server_default="q"
     )
+
+def test_drop_fk():
+    context = op_fixture('mysql')
+    op.drop_constraint("f1", "t1", "foreignkey")
+    context.assert_(
+        "ALTER TABLE t1 DROP FOREIGN KEY f1"
+    )
+
+def test_drop_unique():
+    context = op_fixture('mysql')
+    op.drop_constraint("f1", "t1", "unique")
+    context.assert_(
+        "ALTER TABLE t1 DROP INDEX f1"
+    )
+
+def test_drop_check():
+    context = op_fixture('mysql')
+    assert_raises_message(
+        NotImplementedError,
+        "MySQL does not support CHECK constraints.",
+        op.drop_constraint, "f1", "t1", "check"
+    )
+
+def test_drop_unknown():
+    context = op_fixture('mysql')
+    assert_raises_message(
+        TypeError,
+        "'type' can be one of 'check', 'foreignkey', 'unique', None",
+        op.drop_constraint, "f1", "t1", "typo"
+    )
+
+def test_drop_generic_constraint():
+    context = op_fixture('mysql')
+    assert_raises_message(
+        NotImplementedError,
+        "No generic 'DROP CONSTRAINT' in MySQL - please "
+        "specify constraint type",
+        op.drop_constraint, "f1", "t1"
+    )
\ No newline at end of file