Django恢复最后的迁移
我做了一个迁移,添加了一个新表,并希望恢复它并删除迁移,而不创build新的迁移。
我该怎么做? 有没有命令恢复上次迁移,然后我可以简单地删除迁移文件?
您可以通过迁移到以前的迁移来恢复。
例如,如果您的最后两次迁移是:
-
0010_previous_migration
-
0011_migration_to_revert
那么你会做:
./manage.py migrate my_app 0010_previous_migration
然后,您可以删除迁移0011_migration_to_revert
。
如果您使用的是Django 1.8+,则可以显示所有迁移的名称
./manage.py showmigrations my_app
要为应用程序反转所有迁移,可以运行:
./manage.py migrate my_app zero
阿拉斯代尔的答案涵盖了基本知识
- 通过
./manage.py showmigrations
识别你想要的迁移 - 使用应用程序名称和迁移名称进行迁移
但应该指出的是,并非所有的迁移都可以逆转。 如果Django没有规则去做逆转,就会发生这种情况。 对于大多数通过./manage.py makemigrations
自动进行迁移的更改,都可以进行反转。 但是,自定义脚本需要同时写入正向和反向,如下例所示:
https://docs.djangoproject.com/en/1.9/ref/migration-operations/
如何做一个无操作的逆转
如果你有一个RunPython
操作,那么也许你只是想退出迁移,而不写一个逻辑严谨的反转脚本。 以下对文档示例(上面的链接)的简要说明允许这样做,即使在反转之后,数据库仍处于应用迁移之后的状态。
# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.db import migrations, models def forwards_func(apps, schema_editor): # We get the model from the versioned app registry; # if we directly import it, it'll be the wrong version Country = apps.get_model("myapp", "Country") db_alias = schema_editor.connection.alias Country.objects.using(db_alias).bulk_create([ Country(name="USA", code="us"), Country(name="France", code="fr"), ]) class Migration(migrations.Migration): dependencies = [] operations = [ migrations.RunPython(forwards_func, lambda apps, schema_editor: None), ]
这适用于Django 1.8,1.9
更新:写这个的一个更好的方法是用上面代码片段中的migrations.RunPython.noop
replacelambda apps, schema_editor: None
。 这些都是function上相同的东西。 (信用评论)
另一件你可以做的就是删除手动创build的表。
除此之外,您将不得不删除该特定的迁移文件。 此外,您将不得不删除django-migrations表中的特定条目 (可能是最后一个),这与特定的迁移相关。
这是我的解决scheme,因为上面的解决scheme并没有真正覆盖用例,所以当你使用RunPython
。
您可以通过ORM访问表
from django.db.migrations.recorder import MigrationRecorder >>> MigrationRecorder.Migration.objects.all() >>> MigrationRecorder.Migration.objects.latest('id') Out[5]: <Migration: Migration 0050_auto_20170603_1814 for model> >>> MigrationRecorder.Migration.objects.latest('id').delete() Out[4]: (1, {u'migrations.Migration': 1})
因此,您可以查询表格并删除与您相关的条目。 这样你可以修改细节。 使用RynPython
迁移,您还需要处理添加/更改/删除的数据。 上面的例子只显示了如何通过Djang ORM访问表。
第一部分如何“恢复移民”已经被Alasdair回答了。 我会回答:
…删除迁移,而不创build新的迁移?
TL; DR:您可以删除最后一些还原(困惑)的迁移,并在修复模型后创build一个新的迁移。 您可以使用其他方法设置为不通过migrate命令创build表 ,但必须创build与当前模型匹配的最后一次迁移 。
创build不需要的表的“问题”迁移是由您添加的新Model类导致的。
为什么有人不想拿桌子? 如何解决?
A)在没有机器和没有条件的数据库中不应该存在这样的表格
- 何时:它是另一个模型的基础模型,仅为模型inheritance创build。
- 解决scheme:设置
class Meta: abstract = True
B)表很less被其他东西或以特殊方式手动创build。
- 解决scheme:使用
class Meta: managed = False
迁移是创build,但从来没有使用过,只有在testing。 迁移文件很重要,否则数据库testing无法运行,从可重现的初始状态开始。
C)表格只在某些机器上使用(例如在开发中)。
- 解决scheme:仅在特殊条件下将模型移动到添加到INSTALLED_APPS的新应用程序,或使用条件
class Meta: managed = some_switch
。
D)项目在settings.DATABASES
使用多个数据库
- 解决scheme:使用
allow_migrate
方法写入数据库路由器 ,以便区分可以创build或不能创build表的数据库。
(我忘记了什么?我希望其他所有的东西都为你工作,只有表格不应该被创build,然后例如模型的代理选项中的错误可以被排除。
在B),C),D)中使用Django 1.8创build迁移,在所有情况下使用Django 1.9+创buildABCD,但只在适当的情况下应用于数据库,否则在必要时可能不会。 自从Django 1.8开始运行testing以来,迁移是必要的。 即使对于Django 1.9+中的managed = False的模型,也可以通过迁移来logging完整的相关当前状态,以便可以在托pipe/非托pipe模型之间创buildForeignKey,或者稍后可以使模型managed = True。 (这个问题是在Django 1.8主stream的时候编写的,这里的所有内容在1.8到1.11版本之间都是有效的)。
我在1.9.1中做了这个(删除最后或最近一次创build的迁移):
-
rm <appname>/migrations/<migration #>*
例如:
rm myapp/migrations/0011*
-
login到数据库并运行这个SQL(在这个例子中是postgres)
delete from django_migrations where name like '0011%';
然后,我可以创build新的迁移,以我刚刚删除的迁移编号开始(在本例中为11)。