Python manage.py migrate: настройка и применение миграций

Раздел: Веб-разработка -> django

Основной способ применения migrate

Команда python manage.py migrate применяет все непримененные миграции ко всем приложениям проекта. Она читает файлы миграций, выполняет соответствующие SQL-запросы и обновляет таблицу django_migrations. Для базового использования достаточно выполнить эту команду без дополнительных аргументов.

python manage.py migrate

Python manage py (manage.py в django)

После выполнения в консоли отображается список примененных миграций и статус OK. Если миграции уже были применены, команда ничего не делает. Типичная проблема: конфликт зависимостей между миграциями разных приложений. Решение - проверить файлы миграций и, при необходимости, вручную задать порядок с помощью dependencies.

Ошибка: django.db.utils.OperationalError: no such table: myapp_mymodel возникает, если таблица не создана из-за пропущенной миграции. Рекомендуется выполнить python manage.py migrate myapp для конкретного приложения или использовать --fake-initial, если таблица уже существует.

Как применить миграции только для одного приложения?

Укажите имя приложения после migrate. Команда затронет только миграции указанного приложения и его зависимости.

python manage.py migrate myapp

фреймворк python django (фреймворк django в python)

Это полезно, когда вы работаете над одним приложением и не хотите затрагивать остальные. Проблема: если приложение myapp зависит от не примененных миграций другого приложения, команда может завершиться с ошибкой. В таком случае сначала нужно применить миграции зависимостей.

Ошибка: django.db.migrations.exceptions.InconsistentMigrationHistory указывает на несоответствие между ожидаемыми и фактическими миграциями. Решение: выполнить python manage.py migrate без аргументов, чтобы синхронизировать все.

Как откатить миграции до определенной версии?

Используйте имя миграции или zero для полного отката. Например, откат до миграции 0002:

python manage.py migrate myapp 0002

Python run manage py (запуск manage.py в django)

Для полного удаления всех миграций приложения:

python manage.py migrate myapp zero

Python manage py migrate (команда migrate в django)

Откат выполняет обратные операции, записанные в миграциях. Важно: откат может быть опасен, если после применения миграции были внесены изменения вручную. Перед откатом рекомендуется сделать резервную копию базы данных.

Проблема: откат может не сработать, если миграция содержит необратимые операции (например, удаление поля). В таких случаях Django выдаст предупреждение и не выполнит откат. Решение - вручную написать обратную миграцию или использовать --fake для обновления состояния.

Как пометить миграции как выполненные без фактического выполнения?

Флаг --fake записывает миграции в таблицу django_migrations, но не выполняет соответствующий SQL. Это применяется, когда схема базы данных уже соответствует миграциям (например, после ручного изменения).

python manage.py migrate myapp --fake

Также можно применить --fake для отката:

python manage.py migrate myapp 0002 --fake

Этот вариант часто используется при разрешении конфликтов или когда нужно обмануть Django, чтобы он считал определенные миграции выполненными.

Предостережение: неправильное использование --fake может привести к рассинхронизации между состоянием базы данных и миграциями. Рекомендуется применять только после тщательной проверки.

Как создать таблицы для приложений без миграций?

Флаг --run-syncdb создает таблицы для приложений, у которых нет файлов миграций (например, старые приложения или сторонние библиотеки). Он не затрагивает приложения с миграциями.

python manage.py migrate --run-syncdb

Этот флаг полезен при первоначальной настройке проекта, когда некоторые приложения еще не используют миграции. Однако Django рекомендует для всех приложений создавать миграции.

Замечание: если приложение уже имеет миграции, флаг --run-syncdb будет проигнорирован. Для принудительного создания таблиц можно временно удалить папку migrations или использовать --fake-initial.

Как применить миграции для уже существующей базы данных?

Флаг --fake-initial полезен, когда таблицы уже созданы (например, из дампа или при переключении с другого проекта). Django помечает первую миграцию как выполненную, не пытаясь создать уже существующие таблицы.

python manage.py migrate --fake-initial

Обычно используется однократно при подключении к существующей базе. После этого все последующие миграции применяются обычным образом.

Ошибка: если структура таблиц не соответствует ожидаемой в миграции, возникнет OperationalError. Решение - вручную синхронизировать схему или использовать --fake для пропуска отдельных миграций.

Расширенные примеры использования migrate

Применение миграций после изменения модели

После добавления нового поля в модель необходимо создать миграцию, а затем применить ее.

Пример
python manage.py makemigrations myapp
python manage.py migrate myapp

Консольный вывод:

Migrations for 'myapp':
  myapp/migrations/0003_add_field.py
    - Add field new_field to model MyModel
Operations to perform:
  Apply all migrations: myapp
Running migrations:
  Applying myapp.0003_add_field... OK

Откат до нуля с проверкой плана

Перед откатом можно посмотреть, какие операции будут выполнены, с помощью флага --plan.

Пример
python manage.py migrate myapp --plan
python manage.py migrate myapp zero

Результат команды --plan:

Planned operations:
  myapp.0003_add_field: Reverse add field new_field
  myapp.0002_something: Reverse ...

После отката:

Operations to perform:
  Unapply all migrations: myapp
Running migrations:
  Unapplying myapp.0003_add_field... OK
  Unapplying myapp.0002_something... OK

Исправление состояния с помощью --fake после ручного изменения

Если вы вручную добавили поле в БД, а затем создали миграцию, нужно заставить Django считать ее выполненной без повторного SQL.

Пример
python manage.py migrate myapp 0003 --fake

Вывод:

Operations to perform:
  Target specific migration: 0003, from myapp
Running migrations:
  Applying myapp.0003_add_field... FAKED

Создание и выполнение собственной миграции с RunPython

Создайте пустую миграцию с помощью makemigrations --empty, затем добавьте код.

Пример
python manage.py makemigrations myapp --empty

В полученный файл добавьте:

Пример
from django.db import migrations, models

def forwards_func(apps, schema_editor):
    MyModel = apps.get_model('myapp', 'MyModel')
    MyModel.objects.create(name='init')

def reverse_func(apps, schema_editor):
    MyModel = apps.get_model('myapp', 'MyModel')
    MyModel.objects.filter(name='init').delete()

class Migration(migrations.Migration):
    dependencies = [('myapp', '0002_previous')]
    operations = [
        migrations.RunPython(forwards_func, reverse_func),
    ]

Примените миграцию:

Пример
python manage.py migrate myapp

Вывод:

Operations to perform:
  Apply all migrations: myapp
Running migrations:
  Applying myapp.0003_runpython... OK

Разрешение конфликта миграций с помощью слияния

Если две ветки создали миграции с одинаковым номером, возникает конфликт. Django создает миграцию слияния (--merge).

Пример
python manage.py makemigrations --merge

После этого применяется обычная команда migrate. Вывод:

Merging myapp.0003_a and myapp.0003_b:
  Created myapp/0003_merge.py

Миграции с несколькими базами данных

При использовании роутера базы данных можно указать базу с помощью --database.

Пример
python manage.py migrate myapp --database=slave

Это применит миграции к базе slave. Планирование также работает с флагом --database.

Пример
python manage.py migrate myapp --database=slave --plan

Вывод:

Planned operations (on slave):
  myapp.0003_add_field: Apply

Команда migrate в Django - comments

En
Python manage py migrate (python)