Django的南方(迁移工具)是否适用于innodb?

时间:2022-11-24 19:17:40
$ 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.

For some reason I get this when I try it. But my other setups are in MyISAM.

出于某种原因,我在尝试时得到了这个。但我的其他设置是在MyISAM中。

Why doesn't it work in Innodb?

为什么它在Innodb不起作用?

4 个解决方案

#1


4  

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)

InnoDB对外键具有约束,可确保您在执行迁移时不会破坏数据库模型。 (见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)

MyISAM没有对约束的本机支持(尽管如果您选择这样做,似乎可以实现这一点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.

因为MyISAM没有检查您的FK关系,所以您不会收到错误。然而,InnoDB正在进行检查,您的迁移似乎有问题。

#2


3  

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

另请参见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 :-/

当我使用mysql设置时,我遇到了同样的错误,默认表存储引擎是MyISAM,我想使用InnoDB(使用上面链接中找到的配方,我们使用post_syncdb信号来触发转换代码) 。但是,当使用South创建新表时,首先使用MyISAM引擎创建它们,然后转换。我错误地认为InnoDB表没有做他们应该做的事情,而那些实际上是MyISAM;因为表是由信号转换的,所以任何迁移错误都无法取消应用: - /

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

如果您需要使用或创建默认为MyISAM的InnoDB表,可以使用以下方法解决:

# 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...
}

#3


1  

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.

是的,South确实支持InnoDB。您是否可以删除“迁移”文件夹的内容,并重新运行schemamigration,迁移并在此处发布0001_initial文件的结果和内容? PS:确保先备份迁移文件夹或在源代码管理中备份。

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

#4


1  

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.

您不必将其设置为1,因为它是会话变量。

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.

顺便说一下,如果你在迁移方法中设置为0并且在迁移方法结束时返回到1,则它不起作用,因为南方生成带有它们的SQL,但是当它们返回时执行它。

#1


4  

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)

InnoDB对外键具有约束,可确保您在执行迁移时不会破坏数据库模型。 (见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)

MyISAM没有对约束的本机支持(尽管如果您选择这样做,似乎可以实现这一点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.

因为MyISAM没有检查您的FK关系,所以您不会收到错误。然而,InnoDB正在进行检查,您的迁移似乎有问题。

#2


3  

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

另请参见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 :-/

当我使用mysql设置时,我遇到了同样的错误,默认表存储引擎是MyISAM,我想使用InnoDB(使用上面链接中找到的配方,我们使用post_syncdb信号来触发转换代码) 。但是,当使用South创建新表时,首先使用MyISAM引擎创建它们,然后转换。我错误地认为InnoDB表没有做他们应该做的事情,而那些实际上是MyISAM;因为表是由信号转换的,所以任何迁移错误都无法取消应用: - /

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

如果您需要使用或创建默认为MyISAM的InnoDB表,可以使用以下方法解决:

# 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...
}

#3


1  

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.

是的,South确实支持InnoDB。您是否可以删除“迁移”文件夹的内容,并重新运行schemamigration,迁移并在此处发布0001_initial文件的结果和内容? PS:确保先备份迁移文件夹或在源代码管理中备份。

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

#4


1  

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.

您不必将其设置为1,因为它是会话变量。

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.

顺便说一下,如果你在迁移方法中设置为0并且在迁移方法结束时返回到1,则它不起作用,因为南方生成带有它们的SQL,但是当它们返回时执行它。