Django的south(迁移工具)支持innodb吗?

5 投票
4 回答
3135 浏览
提问于 2025-04-16 10:49
$ 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里不行呢?

4 个回答

1

是的,South确实支持InnoDB。你可以试着删除你“migrations”文件夹里的内容,然后重新运行schemamigration和migrate命令,把结果和0001_initial文件的内容发到这里吗?顺便说一下,确保你先备份一下你的migrations文件夹,或者把它放到版本控制里。

rm -fr app/migrations/*
./manage.py schemamigration app --initial
./manage.py migrate app
3

另请参见 https://code.djangoproject.com/wiki/AlterModelOnSyncDB

我在使用默认存储引擎为MyISAM的mysql设置时,遇到过类似的错误。我想使用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...
}
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不会检查你的外键关系,所以你不会收到错误提示。而InnoDB会进行检查,如果有问题,它会告诉你在迁移过程中出现了问题。

撰写回答