]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
- Added new argument ``mssql_drop_foreign_key`` to
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 7 Dec 2013 00:05:53 +0000 (19:05 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 7 Dec 2013 00:05:53 +0000 (19:05 -0500)
:meth:`.Operations.drop_column`.  Like ``mssql_drop_default``
and ``mssql_drop_check``, will do an inline lookup for a
single foreign key which applies to this column, and drop it.
For a column with more than one FK, you'd still need to explicitly
use :meth:`.Operations.drop_constraint` given the name,
even though only MSSQL has this limitation in the first place.

alembic/ddl/mssql.py
alembic/operations.py
docs/build/changelog.rst
tests/test_mssql.py

index e4f2e9ae8906d5ff3a3bbcdd52300fa880722cbc..095dbf347158cf4f95e39d0bd2fa4e4a2d60a202 100644 (file)
@@ -116,6 +116,12 @@ class MSSQLImpl(DefaultImpl):
                         table_name, column,
                         'sys.check_constraints')
             )
+        drop_fks = kw.pop('mssql_drop_foreign_key', False)
+        if drop_fks:
+            self._exec(
+                _exec_drop_col_fk_constraint(self,
+                        table_name, column)
+            )
         super(MSSQLImpl, self).drop_column(table_name, column)
 
 def _exec_drop_col_constraint(impl, tname, colname, type_):
@@ -126,11 +132,25 @@ select @const_name = [name] from %(type)s
 where parent_object_id = object_id('%(tname)s')
 and col_name(parent_object_id, parent_column_id) = '%(colname)s'
 exec('alter table %(tname)s drop constraint ' + @const_name)""" % {
-        'type':type_,
-        'tname':tname,
-        'colname':colname
+        'type': type_,
+        'tname': tname,
+        'colname': colname
+    }
+
+def _exec_drop_col_fk_constraint(impl, tname, colname):
+    return """declare @const_name varchar(256)
+select @const_name = [name] from
+    sys.foreign_keys fk join sys.foreign_key_columns fkc
+    on fk.object_id=fkc.constraint_object_id
+where fkc.parent_object_id = object_id('%(tname)s')
+and col_name(fkc.parent_object_id, fkc.parent_column_id) = '%(colname)s'
+exec('alter table %(tname)s drop constraint ' + @const_name)""" % {
+        'tname': tname,
+        'colname': colname
     }
 
+
+
 @compiles(AddColumn, 'mssql')
 def visit_add_column(element, compiler, **kw):
     return "%s %s" % (
index 221a764f0edb9070b1ee0ff3a3027816cd3003ef..dfb942b4a6141c9106793550f509e8bac8976933 100644 (file)
@@ -394,6 +394,17 @@ class Operations(object):
          SQL-script-compatible
          block that selects into a @variable from sys.default_constraints,
          then exec's a separate DROP CONSTRAINT for that default.
+        :param mssql_drop_foreign_key: Optional boolean.  When ``True``, on
+         Microsoft SQL Server only, first
+         drop a single FOREIGN KEY constraint on the column using a
+         SQL-script-compatible
+         block that selects into a @variable from
+         sys.foreign_keys/sys.foreign_key_columns,
+         then exec's a separate DROP CONSTRAINT for that default.  Only
+         works if the column has exactly one FK constraint which refers to
+         it, at the moment.
+
+         .. versionadded:: 0.6.2
 
         """
 
index 4d5ae5abf7a0fe9e6feab95cea3b35b6da23bbdb..f960c59f541263d9464058d677e965ae0818d97b 100644 (file)
@@ -6,6 +6,17 @@ Changelog
 .. changelog::
     :version: 0.6.2
 
+    .. change::
+      :tags: feature, mssql
+
+      Added new argument ``mssql_drop_foreign_key`` to
+      :meth:`.Operations.drop_column`.  Like ``mssql_drop_default``
+      and ``mssql_drop_check``, will do an inline lookup for a
+      single foreign key which applies to this column, and drop it.
+      For a column with more than one FK, you'd still need to explicitly
+      use :meth:`.Operations.drop_constraint` given the name,
+      even though only MSSQL has this limitation in the first place.
+
     .. change::
       :tags: bug, mssql
       :pullreq: bitbucket:13
index c0182b2dc533cb0a12139d2bb18ef6f83c931d35..382c99ce17a1b42798109f33aa6939b746a623f8 100644 (file)
@@ -110,6 +110,12 @@ class OpTest(TestCase):
             "ALTER TABLE t ALTER COLUMN c INTEGER NULL"
         )
 
+    def test_drop_column_w_fk(self):
+        context = op_fixture('mssql')
+        op.drop_column('t1', 'c1', mssql_drop_foreign_key=True)
+        context.assert_contains("exec('alter table t1 drop constraint ' + @const_name)")
+        context.assert_contains("ALTER TABLE t1 DROP COLUMN c1")
+
     def test_alter_column_not_nullable_w_existing_type(self):
         context = op_fixture('mssql')
         op.alter_column("t", "c", nullable=False, existing_type=Integer)