代码之家  ›  专栏  ›  技术社区  ›  Cesar Canassa

删除Sql Server中的级联

  •  3
  • Cesar Canassa  · 技术社区  · 16 年前

    South执行以下方法来删除表:

    def delete_table(self, table_name, cascade=True):
        """
        Deletes the table 'table_name'.
        """
        params = (self.quote_name(table_name), )
        if cascade:
            self.execute('DROP TABLE %s CASCADE;' % params)
        else:
            self.execute('DROP TABLE %s;' % params)
    
    drop_table = alias('delete_table')
    

    pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near the keyword 'CASCADE'. (156) (SQLExecDirectW)")
    

    我想为南方写一个补丁,这样它就可以与Sql Server一起工作了。什么样的方法是模拟瀑布的最佳方法?我认为使用python或纯SQL的两种解决方案都是有效的。

    2 回复  |  直到 16 年前
        1
  •  2
  •   hobs axoplasm    12 年前

    def delete_table(self, table_name, cascade=True):
        """
        Deletes the table 'table_name'.
        """
        params = (self.quote_name(table_name), )
        if cascade:
            conn = self._get_connection()
    
            # Get a list of related tables
            sql = "SELECT T1.TABLE_NAME \
                     FROM INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE AS T1 \
                     JOIN SYS.FOREIGN_KEYS AS F \
                       ON (F.parent_object_id = OBJECT_ID(N'{0}') OR \
                          F.referenced_object_id = OBJECT_ID(N'{0}')) AND \
                          T1.CONSTRAINT_NAME = OBJECT_NAME(F.object_id)"
    
            related_tables = self.execute(sql.format(params[0]))
    
            # Drop all the constraints
            constraints = self.execute("SELECT CONSTRAINT_NAME \
                                        FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS \
                                        WHERE TABLE_NAME='{0}' AND \
                                        CONSTRAINT_TYPE='FOREIGN KEY';".format(table_name))
    
            sql = "ALTER TABLE {0} DROP CONSTRAINT {1};"
            for constraint in constraints:
                self.execute(sql.format(params[0], constraint[0]))
    
            for table in related_tables:
                self.delete_table(table[0], cascade)
    
            sql = "IF  EXISTS (SELECT * \
                               FROM sys.objects \
                               WHERE object_id = OBJECT_ID(N'{0}') AND \
                               type in (N'U')) \
                   DROP TABLE {0}"
    
            self.execute(sql.format(params[0]))
        else:
            self.execute('DROP TABLE %s;' % params)
    
        2
  •  1
  •   Pondlife    16 年前

    如果它的意思是“忽略MSSQL的cascade参数”,那么您只需检查当前使用的SQL平台/方言,然后做任何您喜欢的事情(我不知道如何/如果这是可能的)。如果需要,sqlalchemy方言实现可能会给您一些有用的想法。

    但是,如果您想实际实现该功能,则需要查询系统视图来构建要删除的表的列表,以及正确的顺序。架构视图或系统外键应该有帮助。一旦有了一个以正确顺序获取依赖表的查询,就可以修补函数来执行实际的删除操作。