Я сделал миграцию, которая добавила новую таблицу и хочет ее вернуть и удалить перенос, не создавая новую миграцию.
Как мне это сделать? Есть ли команда для возврата последней миграции, а затем я могу просто удалить файл миграции?
Я сделал миграцию, которая добавила новую таблицу и хочет ее вернуть и удалить перенос, не создавая новую миграцию.
Как мне это сделать? Есть ли команда для возврата последней миграции, а затем я могу просто удалить файл миграции?
Вы можете вернуться, перенести на предыдущую миграцию.
Например, если ваши последние две миграции:
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
Ответ Alasdair охватывает основы
./manage.py showmigrations
migrate
, используя имя приложения и имя миграцииНо следует отметить, что не все миграции могут быть отменены. Это происходит, если Django не имеет правила для разворота. Для большинства изменений, которые вы автоматически совершили миграции с помощью ./manage.py makemigrations
, изменение будет возможным. Тем не менее, пользовательские скрипты должны иметь как обратную, так и обратную запись, как описано в примере здесь:
https://docs.djangoproject.com/en/1.9/ref/migration-operations/
Если у вас была операция RunPython
, возможно, вы просто захотите отменить миграцию, не написав логически строгую разворот script. Следующий быстрый взлом к примеру из документов (выше ссылки) позволяет это, оставив базу данных в том же состоянии, что и после миграции, даже после ее изменения.
# -*- 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
в приведенном выше фрагменте. Это функционально одно и то же. (кредит на комментарии)
Другое, что вы можете сделать, это удалить таблицу, созданную вручную.
Кроме того, вам придется удалить этот файл миграции. Кроме того, вам нужно удалить эту конкретную запись в таблице django-migigration (возможно, последней в вашем случае), которая коррелирует с этой конкретной миграцией.
Я сделал это в 1.9.1 (чтобы удалить последнюю или последнюю созданную миграцию):
rm <appname>/migrations/<migration #>*
Пример: rm myapp/migrations/0011*
зашел в базу данных и запустил этот SQL (postgres в этом примере)
delete from django_migrations where name like '0011%';
Затем мне удалось создать новые миграции, которые начались с номера миграции, который я только что удалил (в этом случае 11).
Вот мое решение, так как вышеупомянутое решение на самом деле не распространяется на прецедент, когда вы используете 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. Я отвечу:
... удалить миграцию, не создавая новую миграцию?
TL; DR: Вы можете удалить несколько последних возвращенных (запутанных) миграций и создать новый после фиксации моделей. Вы можете использовать другие средства для настройки , чтобы не создавать таблицу командой migrate, но необходимо создать последнюю миграцию, соответствующую текущим моделям.
"Проблематичная" миграция, которая создала нежелательную таблицу, вызвана добавленным вами новым классом.
Почему кто-то может не получить таблицу? Как его решить?
A) Нет такой таблицы, которая не должна существовать ни в одной базе данных ни на одной машине, ни при каких условиях
class Meta: abstract = True
B) Таблица создается редко, чем-то другим или вручную специальным способом.
class Meta: managed = False
C) Таблица используется только на некоторых машинах (например, в разработке).
class Meta: managed = some_switch
. D) Проект использует несколько баз данных в settings.DATABASES
allow_migrate
, чтобы различать базы данных, в которых таблица может быть создана или не может быть создана.(Я что-то забыл? Я ожидаю, что все остальное сработает для вас, только таблица не должна быть создана. Тогда, например, ошибка в прокси-параметре модели может быть исключена.)
Миграция создается в случаях B), C), D) с Django 1.8 и во всех случаях ABCD с Django 1.9+, но применяется к базе данных только в соответствующих случаях или, может быть, никогда, если это требуется. Для запуска тестов с Django 1.8 необходимы миграции. Полное соответствующее текущее состояние записывается миграциями даже для моделей с управляемым = False в Django 1.9+, чтобы можно было создать ForeignKey между управляемыми/неуправляемыми моделями или сделать модель управляемой = True позже. (Этот вопрос был написан во время основного потока Django 1.8. Все здесь должно быть верным для версий от 1,8 до текущего 1.11.)
Если вы столкнулись с проблемой при возврате миграции и каким-то образом испортили ее, вы можете выполнить fake
миграции.
./manage.py migrate <name> --ignore-ghost-migrations --merge --fake
Для версии django <1.4 это создаст запись в таблице south_migrationhistory
, вам нужно удалить эту запись.
Теперь вы сможете легко вернуться к миграции.
PS: я застрял на много времени, и мне пришлось выполнить ложную миграцию, а затем вернуться назад.