$ py manage.py migrate turkey
Running migrations for turkey:
- Migrating forwards to 0001_initial.
> turkey:0001_initial
! Error found during real run of migration! Aborting.
! Since you have a database that does not support running
! schema-altering statements in transactions, we have had
! to leave it in an interim state between migrations.
! You *might* be able to recover with: = DROP TABLE `turkey_demorecs` CASCADE; []
! The South developers regret this has happened, and would
! like to gently persuade you to consider a slightly
! easier-to-deal-with DBMS.
! NOTE: The error which caused the migration to fail is further up.
出于某种原因,我在尝试时会得到这个。 但我的其他设置是在MyISAM中。
为什么它在Innodb不起作用?
答案 0 :(得分:4)
InnoDB对外键有约束,可确保您在执行迁移时不会破坏数据库模型。 (见http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html)
MyISAM没有对约束的原生支持(尽管如果你选择这样做,你似乎可以实现这一点http://dev.mysql.com/tech-resources/articles/mysql-enforcing-foreign-keys.html)
由于MyISAM未检查您的FK关系,因此您不会收到错误消息。然而,InnoDB正在进行检查,您的迁移似乎存在问题。
答案 1 :(得分:3)
另见https://code.djangoproject.com/wiki/AlterModelOnSyncDB
我在使用mysql设置时发生了同样的错误,默认表存储引擎是MyISAM,我想使用InnoDB(使用上面链接中的配方,我们使用了post_syncdb
信号触发转换代码)。但是,当使用South创建新表时,他们首先使用MyISAM引擎创建,然后转换。我错误地认为InnoDB表没有做他们应该做的事情,而那些实际上是MyISAM;因为表是由信号转换的,所以任何迁移错误都将无法应用: - /
如果您需要使用或创建默认为MyISAM的InnoDB表,可以通过以下方式解决:
# add at the beginning of your migration
if db.backend_name == 'mysql':
db.execute('SET storage_engine=INNODB')
或者如果你不介意性能打击:
# add this to settings.py
DATABASE_OPTIONS = {
"init_command": "SET storage_engine=INNODB", # XXX: performance hit...
}
答案 2 :(得分:1)
是的,South确实支持InnoDB。您是否可以删除“迁移”文件夹的内容,并重新运行schemamigration,迁移并在此处发布0001_initial文件的结果和内容? PS:确保先备份迁移文件夹或首先在源代码管理中备份。
rm -fr app/migrations/*
./manage.py schemamigration app --initial
./manage.py migrate app
答案 3 :(得分:1)
您可以尝试添加第一次迁移:
if db.backend_name == 'mysql':
db.execute('SET foreign_key_checks=0')
这将禁用外键检查约束。
您不必将其设置为1,因为它是会话变量。
顺便说一下,如果你在开始时设置为0并且在迁移方法结束时又设置为1,则它不起作用,因为南方生成SQL,但是当它们返回时执行它。