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.noopreplacelambda 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的迁移):

  1. rm <appname>/migrations/<migration #>*

    例如: rm myapp/migrations/0011*

  2. login到数据库并运行这个SQL(在这个例子中是postgres)

    delete from django_migrations where name like '0011%';

然后,我可以创build新的迁移,以我刚刚删除的迁移编号开始(在本例中为11)。