django恢复上次迁移

时间:2015-08-20 16:24:31

标签: django django-migrations

我已经进行了迁移,添加了一个新表,希望还原它并删除迁移,而不创建新的迁移。

我该怎么办?是否有恢复上次迁移的命令,然后我可以删除迁移文件?

11 个答案:

答案 0 :(得分:599)

您可以通过迁移到之前的迁移来恢复。

例如,如果您的最后两次迁移是:

  • 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

答案 1 :(得分:28)

Alasdair的答案涵盖了基础知识

  • 通过./manage.py showmigrations
  • 确定所需的迁移
  • migrate使用应用名称和迁移名称

但应该指出的是,并非所有迁移都可以。如果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

更新:更好的方法是将lambda apps, schema_editor: None替换为上面代码段中的migrations.RunPython.noop。这些在功能上都是一样的。 (信用评论)

答案 2 :(得分:20)

在还原后才删除迁移文件。我犯了这个错误,没有迁移文件,数据库不知道要删除什么内容。

git pull origin minimalExample

删除迁移文件。在模型中完成所需的迁移后……

python manage.py showmigrations
python manage.py migrate {app name from show migrations} {00##_migration file.py}

答案 3 :(得分:12)

要恢复迁移:

python manage.py migrate <APP_NAME> <MIGRATION_NUMBER_PREFIX>

MIGRATION_NUMBER_PREFIX 是您要还原到的迁移的编号前缀,例如 0001 转到 0001_initial.py 迁移。然后您可以删除该迁移。

<块引用>

您可以使用 zero 作为迁移编号来还原应用的所有迁移。

答案 4 :(得分:9)

您可以做的另一件事是删除手动创建的表。

除此之外,您还必须删除该特定的迁移文件。此外,您必须删除django-migrations表中的特定条目(可能是您案例中的最后一个条目),该条目与该特定迁移相关。

答案 5 :(得分:6)

这是我的解决方案,因为当您使用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访问表。

答案 6 :(得分:6)

您可以通过迁移到上一个迁移来还原。

例如,使用以下命令:

./manage.py migrate example_app one_left_to_the_last_migration

然后删除last_migration文件。

答案 7 :(得分:5)

我在1.9.1中做了这个(删除创建的最后一次或最新的迁移):

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

    示例: rm myapp/migrations/0011*

  2. 登录数据库并运行此SQL(本例中为postgres)

    delete from django_migrations where name like '0011%';

  3. 然后我能够创建以我刚删除的迁移号码开头的新迁移(在本例中为11)。

答案 8 :(得分:3)

这个答案适用于类似案例如果Alasdair的最佳答案无效。 (例如,如果每次新的迁移都会很快创建不需要的迁移,或者如果迁移的大型迁移无法恢复,或者表已被手动删除。)

  

...删除迁移,而不创建新的迁移?

TL; DR :您可以删除一些最后还原(混乱)的迁移,并在修复模型后再创建一个。您还可以使用其他方法通过migrate命令将其配置为以不创建表必须创建最后一次迁移,使其与当前模型匹配

案例为什么有人不想为必须存在的模型创建表:

A)在没有机器且没有条件的情况下,没有数据库存在这样的表

  • 何时:它是仅为其他模型的模型继承而创建的基本模型。
  • 解决方案:设置class Meta: abstract = True

B)该表很少通过其他方式创建或以特殊方式手动创建。

  • 解决方案:使用class Meta: managed = False
    迁移已创建,但从未在测试中使用过。迁移文件很重要,否则数据库测试无法从可重现的初始状态开始运行。

C)该表仅用于某些机器(例如开发中)。

  • 解决方案:将模型移至仅在特殊条件下添加到INSTALLED_APPS的新应用程序,或使用条件class Meta: managed = some_switch

D)该项目使用settings.DATABASES

中的多个数据库
  • 解决方案:使用方法allow_migrate编写Database router,以便区分应创建表的数据库和不应创建表的数据库。

使用Django 1.9+在所有情况下创建迁移A),B),C),D)(仅在B,C,D和Django 1.8的情况下),但仅在适当情况下应用于数据库或如果需要,可能永远不会。自Django 1.8以来,迁移是运行测试所必需的。即使对于Django 1.9+中具有managed = False的模型,迁移也可以记录完整的相关当前状态,以便可以在托管/非托管模型之间创建ForeignKey,或者可以使模型托管= True。 (这个问题是在Django 1.8时编写的。这里的所有内容都适用于1.8到2.2之间的版本。)

如果上次迁移不易恢复,则可以谨慎(在数据库备份后)执行fake revert ./manage.py migrate --fake my_app 0010_previous_migration,手动删除该表。

如有必要,从固定模型创建固定迁移并应用它而不更改数据库结构./manage.py migrate --fake my_app 0011_fixed_migration

答案 9 :(得分:1)

有一个很好的库可以使用其名为djagno-nomad的库,尽管它与所问的问题没有直接关系,但考虑到共享这一问题,

场景:大多数时候切换到项目时,我们认为它应该还原我们在当前分支上所做的更改,这正是该库所做的,请在下面检出

https://pypi.org/project/django-nomad/

答案 10 :(得分:0)

如果在恢复迁移时遇到麻烦,并且由于某种原因将其弄乱了,则可以执行fake迁移。

./manage.py migrate <name> --ignore-ghost-migrations --merge --fake

对于 django版本<1.7 ,这将在south_migrationhistory表中创建条目,您需要删除该条目。

现在,您将能够轻松地还原迁移。

PS:我被困了很多时间,进行了虚假的迁移,然后又恢复原状,这帮助了我。