为什么我的南迁移不工作?
首先,我创建了我的数据库。
create database mydb;
然后,我在已安装的应用里添加了“south”。接着,我去看这个教程:http://south.aeracode.org/docs/tutorial/part1.html
这个教程让我做这个:
$ py manage.py schemamigration wall --initial
>>> Created 0001_initial.py. You can now apply this migration with: ./manage.py migrate wall
太好了,现在我开始迁移。
$ py manage.py migrate wall
但是它给了我这个错误……
django.db.utils.DatabaseError: (1146, "Table 'fable.south_migrationhistory' doesn't exist")
于是我用谷歌搜索(不过这总是没用,所以我在Stackoverflow上问了870个问题),然后我找到了这个页面:http://groups.google.com/group/south-users/browse_thread/thread/d4c83f821dd2ca1c
好吧,我按照那个说明去做
>> Drop database mydb;
>> Create database mydb;
$ rm -rf ./wall/migrations
$ py manage.py syncdb
但是当我运行syncdb时,Django创建了一堆表。是的,它创建了south_migrationhistory表,但它也创建了我应用的表。
Synced:
> django.contrib.admin
> django.contrib.auth
> django.contrib.contenttypes
> django.contrib.sessions
> django.contrib.sites
> django.contrib.messages
> south
> fable.notification
> pagination
> timezones
> fable.wall
> mediasync
> staticfiles
> debug_toolbar
Not synced (use migrations):
-
(use ./manage.py migrate to migrate these)
太好了……现在它让我迁移这些表。所以,我这样做:
$ py manage.py migrate wall
The app 'wall' does not appear to use migrations.
好吧,那我就把wall添加到初始迁移里。
$ py manage.py schemamigration wall --initial
然后我进行迁移:
$ py manage.py migrate wall
你知道吗?它给了我这个无厘头的错误:
_mysql_exceptions.OperationalError: (1050, "Table 'wall_content' already exists")
抱歉,这真的让我很生气。有人能帮帮我吗?谢谢。
我该怎么让South正常工作并与一切同步?我唯一能想到的就是把我的应用从INSTALLED_APPS里移除,然后运行syncdb,再把它加回来。
这真是太傻了。
6 个回答
你正在使用的教程提到:
(如果出现错误提示说 south_migrationhistory 不存在,那是因为你在安装 South 后忘记运行 syncdb 了。)
假设你的帖子准确描述了你所做的步骤,跟着那个链接看起来你在设置新应用之前漏掉了一步。因为你是在跟着一个关于新应用迁移的教程,所以步骤的顺序是:
- 把 south 加入到
INSTALLED_APPS
中。 - 运行
syncdb
。 - 然后再继续跟着教程。
也就是说,你应该在添加新应用的模型之前就已经运行过 syncdb
。你把应用从 INSTALLED_APPS
中移除的解决办法是可以的,但要注意这其实只是一个“笨办法”,因为你之前漏掉了一步。如果在创建那个应用的模型之前就运行过 syncdb
,你就不需要用这个笨办法了。
这是我让事情运作起来的方法。
pip install South
# add 'south', to INSTALL_APPS, then
python manage.py syncdb
# For existing project + database
python manage.py convert_to_south app_name
# Thereafter, call them per model changes
python manage.py schemamigration app_name --auto
python manage.py migrate app_name
参考资料:
http://garmoncheg.blogspot.com/2011/08/django-how-and-why-to-use-migrations.html http://www.djangopro.com/2011/01/django-database-migration-tool-south-explained/
South 是一个工具,可以帮助你在刚开始做新应用时创建数据库迁移,特别是当你的数据库里还没有表的时候。同时,它也可以用于已经有表的旧应用。关键是要知道什么时候该做什么。
你第一次犯的错误是删除了你的迁移文件。你一删除,然后再运行 syncdb,Django 就不知道你想让 South 管理这个应用了,所以它自己创建了表。当你创建了初始迁移后再运行 migrate,South 就试图创建那些 Django 已经创建的表,这就导致了错误。
现在你有两个选择。
从数据库中删除 wall 应用的表,然后运行
$ py manage.py migrate wall
。这样会执行迁移并创建你的表。假装初始迁移已经运行过,运行
$ py manage.py migrate wall 0001 --fake
。这会告诉 South 你已经在数据库里有表了,所以就假装一下,这样会在 south_migrationhistory 表中添加一行记录,下次你运行迁移时,它就知道第一次迁移已经完成。
设置一个全新的项目,没有数据库
- 创建你的数据库。
- 把 South 加入已安装的应用列表。
- 运行 syncdb,这会把 Django 和 South 的表添加到数据库中。
- 添加你的应用。
- 对每个应用运行
python manage.py schemamigration app_name --initial
,这会为你的应用创建初始迁移文件。 - 然后运行 South 的迁移
python manage.py migrate app_name
,这会把表添加到数据库中。
设置一个旧项目和已有数据库
- 把 South 加入已安装的应用列表。
- 运行 syncdb,这会把 South 的表添加到数据库中。
- 对每个应用运行
python manage.py schemamigration app_name --initial
,这会创建你的初始迁移。 - 对每个应用运行
python manage.py migrate app_name 0001 --fake
,这会让 South 假装一下,不会对这些模型做任何数据库操作,只会在 south_migrationhistory 表中添加记录,这样下次你想创建迁移时就准备好了。
设置一个旧项目,没有数据库
- 创建数据库。
- 把 South 加入已安装的应用列表。
- 对每个应用运行
python manage.py schemamigration app_name --initial
,这会创建你的初始迁移。 - 运行 syncdb,这会把没有迁移的应用添加到数据库中。
- 然后运行 South 的迁移
python manage.py migrate
,这会运行你所有应用的迁移。
现在你已经设置好 South,可以开始用它来管理这些应用的模型变更。最常用的命令是 python manage.py schemamigration app_name migration_name --auto
,这个命令会查看你上次运行的迁移,找到变更并为你生成一个迁移文件。然后你只需要运行 python manage.py migrate
,它就会帮你修改数据库。