]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
- Added quoting to the table name when the special EXEC is run to
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 25 Mar 2014 23:16:15 +0000 (19:16 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 25 Mar 2014 23:16:15 +0000 (19:16 -0400)
drop any existing server defaults or constraints when the
:paramref:`.drop_column.mssql_drop_check` or
:paramref:`.drop_column.mssql_drop_default`
arguments are used.  fix #186

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

index 58b57cf18a1d39c1110d449bc609b13185239587..7bfe2932bc42280c0eba30f747de77be9cca07d6 100644 (file)
@@ -5,6 +5,7 @@ from .impl import DefaultImpl
 from .base import alter_table, AddColumn, ColumnName, \
     format_table_name, format_column_name, ColumnNullable, alter_column,\
     format_server_default,ColumnDefault, format_type, ColumnType
+from sqlalchemy.sql.expression import ClauseElement, Executable
 
 class MSSQLImpl(DefaultImpl):
     __dialect__ = 'mssql'
@@ -70,7 +71,7 @@ class MSSQLImpl(DefaultImpl):
             if existing_server_default is not False or \
                 server_default is None:
                 self._exec(
-                    _exec_drop_col_constraint(self,
+                    _ExecDropConstraint(
                             table_name, column_name,
                             'sys.default_constraints')
                 )
@@ -105,48 +106,66 @@ class MSSQLImpl(DefaultImpl):
         drop_default = kw.pop('mssql_drop_default', False)
         if drop_default:
             self._exec(
-                _exec_drop_col_constraint(self,
+                _ExecDropConstraint(
                         table_name, column,
                         'sys.default_constraints')
             )
         drop_check = kw.pop('mssql_drop_check', False)
         if drop_check:
             self._exec(
-                _exec_drop_col_constraint(self,
+                _ExecDropConstraint(
                         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)
+                _ExecDropFKConstraint(table_name, column)
             )
         super(MSSQLImpl, self).drop_column(table_name, column)
 
-def _exec_drop_col_constraint(impl, tname, colname, type_):
+class _ExecDropConstraint(ClauseElement, Executable):
+    def __init__(self, tname, colname, type_):
+        self.tname = tname
+        self.colname = colname
+        self.type_ = type_
+
+class _ExecDropFKConstraint(ClauseElement, Executable):
+    def __init__(self, tname, colname):
+        self.tname = tname
+        self.colname = colname
+
+
+@compiles(_ExecDropConstraint, 'mssql')
+def _exec_drop_col_constraint(element, compiler, **kw):
+    tname, colname, type_ = element.tname, element.colname, element.type_
     # from http://www.mssqltips.com/sqlservertip/1425/working-with-default-constraints-in-sql-server/
     # TODO: needs table formatting, etc.
     return """declare @const_name varchar(256)
 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)""" % {
+exec('alter table %(tname_quoted)s drop constraint ' + @const_name)""" % {
         'type': type_,
         'tname': tname,
-        'colname': colname
+        'colname': colname,
+        'tname_quoted': format_table_name(compiler, tname, None),
     }
 
-def _exec_drop_col_fk_constraint(impl, tname, colname):
+@compiles(_ExecDropFKConstraint, 'mssql')
+def _exec_drop_col_fk_constraint(element, compiler, **kw):
+    tname, colname = element.tname, element.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)""" % {
+exec('alter table %(tname_quoted)s drop constraint ' + @const_name)""" % {
         'tname': tname,
-        'colname': colname
+        'colname': colname,
+        'tname_quoted': format_table_name(compiler, tname, None),
     }
 
 
index 8ba2855fe3ad9c5858c05c2de5cf2dd7b11c04b6..a2ab35a8e29de236c56f740b830c6cfc6ad123ed 100644 (file)
@@ -5,6 +5,16 @@ Changelog
 .. changelog::
     :version: 0.6.4
 
+    .. change::
+      :tags: bug, mssql
+      :tickets: 186
+
+      Added quoting to the table name when the special EXEC is run to
+      drop any existing server defaults or constraints when the
+      :paramref:`.drop_column.mssql_drop_check` or
+      :paramref:`.drop_column.mssql_drop_default`
+      arguments are used.
+
     .. change::
       :tags: bug, mysql
       :tickets: 103
index d87f62a8d59d45ba20fa0af0bc40e5c5cf28a549..5fa6c4b2c15a1d1fa25051993d39c7abed91ecee 100644 (file)
@@ -113,6 +113,12 @@ class OpTest(TestCase):
         context.assert_contains("exec('alter table t1 drop constraint ' + @const_name)")
         context.assert_contains("ALTER TABLE t1 DROP COLUMN c1")
 
+    def test_drop_column_w_check_quoting(self):
+        context = op_fixture('mssql')
+        op.drop_column('table', 'column', mssql_drop_check=True)
+        context.assert_contains("exec('alter table [table] drop constraint ' + @const_name)")
+        context.assert_contains("ALTER TABLE [table] DROP COLUMN [column]")
+
     def test_alter_column_nullable_w_existing_type(self):
         context = op_fixture('mssql')
         op.alter_column("t", "c", nullable=True, existing_type=Integer)