South不会为已有应用生成或应用迁移,尽管有迁移的更改
我正在使用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 个回答
另外要注意,如果你在使用像 Johnny Cache 这样的查询集缓存,单纯从数据库中删除迁移历史是没用的。你需要要么停止 memcached 服务:killall memcached
,要么对于在生产环境中的项目,你需要使用以下命令来使 south_migrationhistory 表失效,命令是通过 python manage.py shell
来执行的:
from johnny.cache import invalidate
invalidate('south_migrationhistory')
这就是我遇到的情况。
我想你可能是因为没有先运行 ./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
,这样可以进行第一次迁移,并且删除你之前从迁移文件夹中删除的旧的第一次迁移记录。
来自一些不太光彩的黑科技:
这个方法解决了我的问题,但实在不算优雅。
(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
)
欢迎提供更好更干净的建议,也欢迎指出这个方法可能会破坏的其他内容。