Как отменить последнюю миграцию?
Я создал миграцию, которая добавила новую таблицу, и хочу откатить её, а также удалить саму миграцию, не создавая новую.
Как это сделать? Есть ли команда для отката последней миграции, после чего я смогу просто удалить файл миграции?
5 ответ(ов)
Ответ пользователя Alasdair охватывает основные моменты:
- Определите миграции, которые хотите применить, с помощью команды
./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):
# Мы получаем модель из реестра приложений с версионностью;
# если мы импортируем ее напрямую, будет неверная версия
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
.
Вы можете получить доступ к таблице через 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})
Таким образом, вы можете запрашивать таблицы и удалять те записи, которые вам нужны. Так вы сможете более детально модифицировать данные. При использовании миграций RunPython
также необходимо учитывать данные, которые были добавлены, изменены или удалены. Приведенный выше пример лишь демонстрирует, как получить доступ к таблице через ORM Django.
Чтобы откатить миграцию, выполните следующую команду:
python manage.py migrate <ИМЯ_ПРИЛОЖЕНИЯ> <ПРЕФИКС_НОМЕРА_МИГРАЦИИ>
ПРЕФИКС_НОМЕРА_МИГРАЦИИ
— это числовой префикс миграции, к которой вы хотите откатиться. Например, если вы хотите вернуться к миграции 0001_initial.py
, используйте 0001
. После этого вы можете удалить указанную миграцию.
Вы также можете использовать
zero
в качестве номера миграции, чтобы откатить все миграции для приложения.
Чтобы откатить миграции вашего приложения, сначала найдите предыдущие миграции с помощью команды:
python manage.py showmigrations
Например:
bz
[X] 0001_initial
[ ] 0002_bazifff
Если вы хотите откатить миграции 0002_bazifff, используйте следующую команду:
python manage.py migrate bz 0001_initial
Если вы хотите откатить 0001_initial или все миграции, выполните:
python manage.py migrate bz zero
Обратите внимание, что откатить только 0001 невозможно, так как это первая миграция в вашем приложении.
Для удаления последней или самой последней миграции, созданной в Django 1.9.1, выполните следующие шаги:
Удалите миграцию с помощью команды:
rm <имя_приложения>/migrations/<номер_миграции>*
например:
rm myapp/migrations/0011*
Затем войдите в базу данных и выполните следующий SQL-запрос (в данном примере используется PostgreSQL):
DELETE FROM django_migrations WHERE name LIKE '0011%';
После выполнения этих шагов вы сможете создать новые миграции, начиная с номера миграции, которую только что удалили (в данном случае, номер 11).
Существует ли список временных зон Pytz?
Как выполнить фильтрацию запросов в Django по условию "не равно"?
Превысил ли Django 100 тыс. посещений в день? [закрыто]
В чем разница между null=True и blank=True в Django?
Как отсортировать список/кортеж списков/кортежей по элементу на заданном индексе