South不会为已有应用生成或应用迁移,尽管有迁移的更改

8 投票
4 回答
3227 浏览
提问于 2025-04-17 01:25

我正在使用South来生成和应用数据库迁移,而不是自己来管理这些事情。不幸的是,South似乎不愿意真正执行任何操作。下面是我的操作记录:

[graffias:~/testing.tustincommercial.com/oneclickcos]$ python ./manage.py schemamigration mainapp --auto
You cannot use --auto on an app with no migrations. Try --initial.
[graffias:~/testing.tustincommercial.com/oneclickcos]$ python ./manage.py schemamigration mainapp --initial
 + Added model mainapp.CompanyUK
 + Added model mainapp.CompanyName
 + Added model mainapp.Individual
 + Added model mainapp.Director
 + Added model mainapp.DirectorsIndividual
 + Added model mainapp.DirectorsCorporate
 + Added model mainapp.ShareCapitalClass
 + Added model mainapp.Member
 + Added model mainapp.MembersIndividual
 + Added model mainapp.MemberGeneric
 + Added model mainapp.CompanyManager
 + Added model mainapp.PendingRegistration
 + Added model mainapp.PendingAuthorisation
Created 0001_initial.py. You can now apply this migration with: ./manage.py migrate mainapp
[graffias:~/testing.tustincommercial.com/oneclickcos]$ python ./manage.py migrate mainapp
Running migrations for mainapp:
- Nothing to migrate.
 - Loading initial data for mainapp.
No fixtures found.
[graffias:~/testing.tustincommercial.com/oneclickcos]$ 

正如你所看到的,South认为没有任何事情需要做。然而,最后三个模型是全新的,在数据库中没有对应的表。

除了重置数据库之外,我还有什么办法可以让South重新工作吗?

我不打算手动为项目的其余部分编写迁移,但如果这样能帮上忙,我可以写一个迁移。

4 个回答

2

另外要注意,如果你在使用像 Johnny Cache 这样的查询集缓存,单纯从数据库中删除迁移历史是没用的。你需要要么停止 memcached 服务:killall memcached,要么对于在生产环境中的项目,你需要使用以下命令来使 south_migrationhistory 表失效,命令是通过 python manage.py shell 来执行的:

from johnny.cache import invalidate
invalidate('south_migrationhistory')

这就是我遇到的情况。

9

我想你可能是因为没有先运行 ./manage.py convert_to_south mainapp 而遇到了麻烦。也许你可以通过以下步骤来解决这个问题:

(1) 让 South 认为你没有进行第一次迁移,所以我们要把状态重置到零。

./manage.py migrate --fake mainapp zero

(2) 真实地进行第一次迁移。

./manage.py migrate mainapp

不过根据你的问题来看,你的数据库里已经有一些模型是没有使用 South 创建的,否则你就不需要用到 --initial 这个选项。如果是这样的话,可能会出现关于列已经存在的错误。

你可以通过以下方法来改变这种情况:

(1) 删除第一个迁移文件,路径是 mainapp/migrations/0001_initial.py。你不需要直接去修改 South 的数据库表,使用 --delete-ghost-migrations 就可以解决这个问题。

(2) 运行 ./manage.py syncdb,因为 South 需要数据库和模型保持同步。

(3) 运行 ./manage.py convert_to_south mainapp,让 South 来管理数据库和迁移。

(4) 运行 ./manage.py migrate --delete-ghost-migrations mainapp,这样可以进行第一次迁移,并且删除你之前从迁移文件夹中删除的旧的第一次迁移记录。

2

来自一些不太光彩的黑科技:

这个方法解决了我的问题,但实在不算优雅。

(1) 删除受影响应用中的所有迁移文件(rm mainapp/migrations/*

(2) 删除你的 models.py 文件,然后用一个空文件替换它(mv mainapp/models.py .; rm mainapp/*.pyc; touch mainapp/models.py

(3) 生成一个初始的迁移文件,这个文件什么都不做(python ./manage.py schemamigration mainapp --initial),然后应用这个迁移(python ./manage.py migrate mainapp

(4) 恢复你的模型,然后生成一个迁移文件,这个文件会重新创建所有内容(rm mainapp/models.py; mv models.py mainapp/; python ./manage.py schemamigration mainapp --auto

(5) 在运行新的迁移之前,编辑它,把所有其实并不是新变化的部分注释掉。或者,你也可以先运行它,让它在实际存在的表上失败,然后再把所有内容注释掉。

(6) 应用你的迁移,让 south 处于一个正常状态(如果你按照我在第(5)步推荐的方式操作,还可以进行你的更改:python ./manage.py migrate mainapp

欢迎提供更好更干净的建议,也欢迎指出这个方法可能会破坏的其他内容。

撰写回答