代码之家  ›  专栏  ›  技术社区  ›  Travis

如何在SQLAlchemy中删除外键约束?

  •  7
  • Travis  · 技术社区  · 16 年前

    t_new = sa.Table("new", meta.metadata,
        sa.Column("new_id", sa.types.Integer, primary_key=True)
    )
    t_exists = sa.Table("exists", meta.metadata,
        sa.Column("exists_id", sa.types.Integer, primary_key=True),
        sa.Column(
            "new_id", 
            sa.types.Integer,
            sa.ForeignKey("new.new_id", onupdate="CASCADE", ondelete="CASCADE"),
            nullable=False
        )
    )
    

    这很好:

    t_new.create()
    t_exists.c.new_id.create()
    

    但这并不是:

    t_exists.c.new_id.drop()
    t_new.drop()
    

    尝试删除外键列时出现错误:1025,“将“.\my_db_name\#sql-1b0_2e6”重命名为“.\my_db_name\ exists”时出错(错误号:150)

    如果我使用原始SQL执行此操作,我可以手动删除外键,然后删除列,但是我还没有弄清楚如何使用SQLAlchemy删除外键?如何删除外键,然后删除列?

    4 回复  |  直到 13 年前
        1
  •  6
  •   prinzdezibel    15 年前

    您可以使用sqlalchemy.migrate来完成。

    为了使它工作,我必须显式地创建外键约束,而不是隐式地使用列('fk',ForeignKey('fk\u table.field')):

    唉,与其这样做:

    p2 = Table('tablename',
                metadata,
                Column('id', Integer, primary_key=True),
                Column('fk', ForeignKey('fk_table.field')),
                mysql_engine='InnoDB',
               )
    

    这样做:

    p2 = Table('tablename',
                metadata,
                Column('id', Integer, primary_key=True),
                Column('fk', Integer, index=True),
                mysql_engine='InnoDB',
                )
    ForeignKeyConstraint(columns=[p2.c.fk], refcolumns=[p3.c.id]).create()
    

    删除过程如下所示:

    def downgrade(migrate_engine):
         # First drop the constraint
         ForeignKeyConstraint(columns=[p2.c.fk], refcolumns=[p3.c.id]).drop()
         # Then drop the table
         p2.drop()
    
        2
  •  3
  •   Travis    16 年前

    我可以通过创建一个单独的元数据实例并使用Session.execute()运行原始SQL来实现这一点。理想情况下,会有一个专门使用sqlalchemy的解决方案,所以我不必使用MySQL特定的解决方案。但到目前为止,我还没有找到这样的解决办法。

        3
  •  0
  •   Michael Hunter    15 年前

        4
  •  -1
  •   van    16 年前

    好吧,你可以在sqlalchemy中实现这一点:只要 drop() 所有的约束都摆在你面前 删除()

    def drop_column(column):
        for fk in column.table.foreign_keys:
            if fk.column == column:
                print 'deleting fk ', fk
                fk.drop()
        column.drop()
    
    drop_column(t_exists.c.new_id)