2012-12-07 73 views
6

我正在尝试使用alembic将“主键”列添加到已有的MySQL表中。我尝试以下...将主键添加到alembic中的现有MySQL表中

op.add_column('mytable', sa.Column('id', sa.Integer(), nullable=False)) 
op.alter_column('mytable', 'id', autoincrement=True, existing_type=sa.Integer(), existing_server_default=False, existing_nullable=False) 

而且得到了以下错误

sqlalchemy.exc.OperationalError: (OperationalError) (1075, 'Incorrect table definition; there can be only one auto column and it must be defined as a key') 'ALTER TABLE mytable CHANGE id id INTEGER NOT NULL AUTO_INCREMENT'() 

看起来像由蒸馏器生成的ALTER语句的结尾没有添加PRIMARY KEY的SQL语句。我可以错过一些设置吗?

在此先感谢!

回答

16

我花了一些时间挖掘alembic源代码,这似乎并不支持。您可以在创建表时指定主键,但在添加列时不能。事实上,它专门检查,不会让你:

# from alembic.operations.add_column, line 284 
for constraint in t.constraints: 
    if not isinstance(constraint, schema.PrimaryKeyConstraint): 
    self.impl.add_constraint(constraint) 

我环顾四周,并添加主键到现有表可能会导致不确定的行为 - 主键不应该为空,所以您的引擎可能会或可能不会为现有行创建主键。请参阅此SO讨论以获取更多信息:Insert auto increment primary key to existing table

我只是直接运行alter query,并在需要时创建主键。

op.execute("ALTER TABLE mytable ADD id INT PRIMARY KEY AUTO_INCREMENT;") 

如果你真的需要跨引擎的兼容性,大铁锤将(1)创建一个新表等同于旧有一个主键,(2)迁移所有数据,(3)删除旧表并(4)重命名新表。

希望有所帮助。