Миграции

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

Django ORM пользуется моделями данных для общения с БД. Но что, если модели захотелось поменять? Для этого программисты придумали миграции.

Миграция — это описание изменений, которые вы хотите внести в таблицы базы данных. Например, у вас есть модель поста в блоге. У модели Post есть только поле text:

from django.db import models

class Post(models.Model):
    text = models.TextField()

Теперь вы захотели добавить новое поле title — заголовок поста:

from django.db import models

class Post(models.Model):
    text = models.TextField()
    title = models.CharField(max_length=200, blank=True)

Просто поменять файл models.py недостаточно. Работа с базой данных — тонкое дело. Для того, чтобы в базе данных произошли изменения, нужно её отмигрировать, т.е. создать миграцию, которая объяснит базе данных, как ей измениться.

blank=True мы добавили для того, чтобы не случилось конфликта, о котором мы говорим в этой статье.

Что же это такое

Каждая миграция — это файл с инструкциями для базы данных. Все они пронумерованы по порядку:

Никто эти файлы не писал, они создаются автоматически, когда вы запускаете команду makemigrations (о ней будет ниже). Запустив makemigrations для примера выше, вы получите такую миграцию:

class Migration(migrations.Migration):

    dependencies = [
        ('APPNAME', '0001_initial'),  # APPNAME — это название папки, где лежит models.py
    ]

    operations = [
        migrations.AddField(
            model_name='post',
            name='title',
            field=models.CharField(max_length=200, blank=True)
        )
    ]

Давайте по кусочкам разберём, что тут написано:

dependencies — это список миграций, которые обязательно нужно провести перед этой. Так как миграции выполняются по порядку, в каждой следующей миграции в поле dependencies будет записана предыдущая. В примере выше показана вторая миграция в проекте, поэтому она зависит от первой. Первая миграция создаёт модель с полем text, а эта прибавила к модели новое поле title. Если мы отмигрируем базу в третий раз, в dependencies окажется ссылка на вторую миграцию:

dependencies = [
        ('APPNAME', '0002_auto'),
    ]

Второй большой блок — это operations. В нём лежит описание всех изменений, которые нужно провести в БД:

operations = [
    migrations.AddField(
        model_name='post',
        name='title',
        field=models.CharField(max_length=200, blank=True)
    )
]

Тут написано, что нужно добавить поле (AddField) к модели поста (model_name='post') с названием "title", и что поле будет текстовым, на 200 символов (field=models.CharField(max_length=200, blank=True)).

makemigrations

Файлы миграций можно писать вручную, но это долго, сложно и легко ошибиться. Для создания миграций автоматически в Django есть команда python manage.py makemigrations. Если миграций ещё не было, то эта команда создаст файл 0001_initial.py в папке migrations, где она опишет все модели для базы данных.

Если вы уже проводили миграции в своём проекте, то Django сравнит текущий файл models.py с историей миграций. Django сама определит, что нужно убрать из моделей, а что — добавить, чтобы отмигрировать базу данных к новым моделям.

migrate

Команда python manage.py migrate запускает миграции в базе данных. В процессе их исполнения вы увидите такой вывод:

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

Что читать

Наши статьи:

Документация:


Попробуйте бесплатные уроки по Python

Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.

Переходите на страницу учебных модулей «Девмана» и выбирайте тему.