我已经进行了一个迁移,添加了一个新的表,现在想回滚并删除该迁移,而不需要创建新的迁移。
我应该如何操作呢?是否有一个命令可以撤销最后一次迁移,然后我只需简单地删除迁移文件即可?
我已经进行了一个迁移,添加了一个新的表,现在想回滚并删除该迁移,而不需要创建新的迁移。
我应该如何操作呢?是否有一个命令可以撤销最后一次迁移,然后我只需简单地删除迁移文件即可?
您可以通过将迁移回滚到上一个版本来恢复。
例如,如果您的最后两次迁移是:
0010_previous_migration0011_migration_to_revert那么您需要执行以下操作:
./manage.py migrate my_app 0010_previous_migration
你实际上不需要使用完整的迁移名称,只需要用数字即可,例如:
./manage.py migrate my_app 0010
您可以删除迁移0011_migration_to_revert。
如果您使用的是Django 1.8+,则可以使用以下命令显示所有迁移的名称:
./manage.py showmigrations my_app
要撤销应用程序的所有迁移,可以运行以下命令:
./manage.py migrate my_app zero
在还原之前不要删除迁移文件。我犯了这个错误,没有迁移文件,数据库就不知道该删除哪些内容。
python manage.py showmigrations
python manage.py migrate {app name from show migrations} {00##_migration file.py}
如果您想还原所有迁移,请使用zero作为迁移的名称:If you want to revert all migrations, use zero as the name of the migration:
python manage.py migrate app_name_here zero
删除迁移文件。一旦您的模型中有所需的迁移...
python manage.py makemigrations
python manage.py migrate
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。它们在功能上是完全相同的。(感谢评论区)
RunPython.noop代替内联的lambda表达式或等效形式:https://docs.djangoproject.com/en/1.8/ref/migration-operations/#django.db.migrations.operations.RunPython.noop - SpoonMeisermigrations.RunPython(forwards_func, migrations.RunPython.noop)。需要检查一下功能。这应该会在某个时候作为答案或编辑添加到这个问题中。 - AlanSE这是我的解决方案,因为上面的解决方案并没有真正涵盖使用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 访问表格。
django.db.utils.ProgrammingError: relation "<relation name>" already exists,因此我进行了migrate --fake,这是错误的,所以我尝试回退,然后我得到了psycopg2.ProgrammingError: relation "<other <relation name>" does not exist。谢谢。 - onekiloparsec撤销迁移:
python manage.py migrate <APP_NAME> <MIGRATION_NUMBER_PREFIX>
MIGRATION_NUMBER_PREFIX 是您想要还原的迁移的数字前缀,例如使用 0001 前缀即可回到 0001_initial.py 迁移。随后,您可以删除该迁移。
您可以将
zero作为应用程序所有迁移的还原号码。
我在1.9.1版本中执行以下操作(删除最后或最新创建的迁移):
rm <appname>/migrations/<migration #>*
示例: rm myapp/migrations/0011*
登录数据库并运行以下SQL(以本例中的postgres为例)
delete from django_migrations where name like '0011%';
然后,我就能够创建新的迁移,并从刚刚删除的迁移号码开始(在这种情况下是11)。
首先,找到您的应用程序的先前迁移:
python manage.py showmigrations
例如:
bz
[X] 0001_initial
[ ] 0002_bazifff
如果你想回滚 0002_bazifff 迁移,
python manage.py migrate bz 0001_initial
如果你想要回滚 0001_initial 或者 全部(all)
python manage.py migrate bz zero
看起来无法仅回滚0001
另一件可以做的事情是手动删除创建的表格。
与此同时,您还需要删除该特定迁移文件。此外,您还需删除 django-migrations 表中与该特定迁移相关的 特定条目(可能是您案例中的最后一个迁移)。
您可以通过迁移到上一个迁移来还原。
例如使用以下命令:
./manage.py migrate example_app one_left_to_the_last_migration
然后删除 last_migration 文件。
如果您在回滚迁移时遇到麻烦,并且不小心搞乱了它,您可以执行“fake”迁移。
./manage.py migrate <name> --ignore-ghost-migrations --merge --fake
对于django版本小于1.7的情况,这将在south_migrationhistory表中创建一个条目,您需要删除该条目。
现在您可以轻松还原迁移。
提示:我卡了很长时间,执行虚假迁移然后还原帮了我。
/manage.py migrate my_app 0010,只需输入0010,而不是完整的文件名。之后,需要手动删除本地文件夹 appname/migrations/0011+ 中的文件,并手动从 django_migrations 数据库表中删除 0011+ 相关的行。 - Emily