Does Django's south (migration tool) work for innodb?

允我心安 提交于 2019-11-30 09:57:02

InnoDB has constraints on Foreign Keys which ensure you are not breaking the database model when doing a migration. (see http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html)

MyISAM does not have native support for constraints (although it seems you can implement this if you choose to do do http://dev.mysql.com/tech-resources/articles/mysql-enforcing-foreign-keys.html)

Because MyISAM is not checking your FK relationships, you do not get the error. InnoDB however is doing a check and it seems that you have a problem with your migration.

See also https://code.djangoproject.com/wiki/AlterModelOnSyncDB

I have had the same kind of error happen to me when working with a mysql setup whose default table storage engine is MyISAM and I wanted to use InnoDB (using the recipe found in above link, we used the post_syncdb signal to trigger the conversion code). However, when using South to create new tables they were first created using MyISAM engine then later converted. I was mistakenly believing InnoDB tables weren't doing what they were supposed to, when those were actually MyISAM; because the table were converted by the signal, any migration error would fail to unapply :-/

If you need to use or create InnoDB tables where the default is MyISAM, this be solved with:

# add at the beginning of your migration
if db.backend_name == 'mysql':
   db.execute('SET storage_engine=INNODB')

or if you do not mind the performance hit:

# add this to settings.py
DATABASE_OPTIONS = {
   "init_command": "SET storage_engine=INNODB", # XXX: performance hit...
}

Yes, South does support InnoDB. Can you delete the contents of your "migrations" folder, and re-run schemamigration, migrate, and post the results and contents of the 0001_initial file here? PS: Make sure you have your migrations folder backed up or in source control first.

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

You could try adding to your first migration:

if db.backend_name == 'mysql':
    db.execute('SET foreign_key_checks=0')

This will disable the foreign key check constraints.

You don't have to set it back to 1 since it's a session variable.

By the way, it doesn't work if you set to 0 at the beggining and back to 1 at the end of your migration method, because south generates SQL with them, but executes it when they return.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!