为什么我的南迁移不工作?

79 投票
6 回答
48768 浏览
提问于 2025-04-16 10:52

首先,我创建了我的数据库。

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 个回答

8

你正在使用的教程提到:

(如果出现错误提示说 south_migrationhistory 不存在,那是因为你在安装 South 后忘记运行 syncdb 。)

假设你的帖子准确描述了你所做的步骤,跟着那个链接看起来你在设置新应用之前漏掉了一步。因为你是在跟着一个关于新应用迁移的教程,所以步骤的顺序是:

  1. south 加入到 INSTALLED_APPS 中。
  2. 运行 syncdb
  3. 然后再继续跟着教程。

也就是说,你应该在添加新应用的模型之前就已经运行过 syncdb。你把应用从 INSTALLED_APPS 中移除的解决办法是可以的,但要注意这其实只是一个“笨办法”,因为你之前漏掉了一步。如果在创建那个应用的模型之前就运行过 syncdb,你就不需要用这个笨办法了。

11

这是我让事情运作起来的方法。

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/

175

South 是一个工具,可以帮助你在刚开始做新应用时创建数据库迁移,特别是当你的数据库里还没有表的时候。同时,它也可以用于已经有表的旧应用。关键是要知道什么时候该做什么。

你第一次犯的错误是删除了你的迁移文件。你一删除,然后再运行 syncdb,Django 就不知道你想让 South 管理这个应用了,所以它自己创建了表。当你创建了初始迁移后再运行 migrate,South 就试图创建那些 Django 已经创建的表,这就导致了错误。

现在你有两个选择。

  1. 从数据库中删除 wall 应用的表,然后运行 $ py manage.py migrate wall。这样会执行迁移并创建你的表。

  2. 假装初始迁移已经运行过,运行 $ py manage.py migrate wall 0001 --fake。这会告诉 South 你已经在数据库里有表了,所以就假装一下,这样会在 south_migrationhistory 表中添加一行记录,下次你运行迁移时,它就知道第一次迁移已经完成。

设置一个全新的项目,没有数据库

  1. 创建你的数据库。
  2. 把 South 加入已安装的应用列表。
  3. 运行 syncdb,这会把 Django 和 South 的表添加到数据库中。
  4. 添加你的应用。
  5. 对每个应用运行 python manage.py schemamigration app_name --initial,这会为你的应用创建初始迁移文件。
  6. 然后运行 South 的迁移 python manage.py migrate app_name,这会把表添加到数据库中。

设置一个旧项目和已有数据库

  1. 把 South 加入已安装的应用列表。
  2. 运行 syncdb,这会把 South 的表添加到数据库中。
  3. 对每个应用运行 python manage.py schemamigration app_name --initial,这会创建你的初始迁移。
  4. 对每个应用运行 python manage.py migrate app_name 0001 --fake,这会让 South 假装一下,不会对这些模型做任何数据库操作,只会在 south_migrationhistory 表中添加记录,这样下次你想创建迁移时就准备好了。

设置一个旧项目,没有数据库

  1. 创建数据库。
  2. 把 South 加入已安装的应用列表。
  3. 对每个应用运行 python manage.py schemamigration app_name --initial,这会创建你的初始迁移。
  4. 运行 syncdb,这会把没有迁移的应用添加到数据库中。
  5. 然后运行 South 的迁移 python manage.py migrate,这会运行你所有应用的迁移。

现在你已经设置好 South,可以开始用它来管理这些应用的模型变更。最常用的命令是 python manage.py schemamigration app_name migration_name --auto,这个命令会查看你上次运行的迁移,找到变更并为你生成一个迁移文件。然后你只需要运行 python manage.py migrate,它就会帮你修改数据库。

撰写回答