Допустим, у вас есть проект, в котором нужно хранить данные пользователей, их заказы и... котиков (куда без них?). Вы создаёте модели в Django, описываете в коде, как выглядят таблицы базы данных, но пока база данных даже не подозревает об их существовании. Чтобы "рассказать" базе данных о наших моделях, нам нужны миграции.
Миграции — это способ преобразования ваших моделей (Python-код) в таблицы базы данных. Они извлекают информацию о моделях и создают SQL-скрипты, которые затем применяются к базе данных.
Зачем нам миграции?
- Управление изменениями: если мы меняем модели (добавляем поле, изменяем тип данных), миграции помогут корректно отразить эти изменения в базе данных.
- Версионность: миграции фиксируют изменения в структуре базы данных. Они работают, как Git для ваших моделей.
- Автоматизация: Django берёт на себя всю работу и генерирует SQL-код за вас. У вас больше времени на мемы про программистов.
Процесс миграции можно разделить на три этапа:
- Извлечение изменений из моделей: Django анализирует текущие и предыдущие состояния моделей.
- Создание файла миграции: файл миграции содержит инструкции по изменению базы данных.
- Применение миграции: Django отправляет SQL-команды базе данных и изменяет её структуру.
Команды для работы с миграциями
Да, миграции могут напугать, но на деле всё очень просто. Django предоставляет нам несколько волшебных команд, которые превращают управление базой данных в удовольствие:
python manage.py makemigrations
Эта команда анализирует ваши модели и генерирует файл миграции. Мы используем её, когда создаём или изменяем модели.
Пример:
$ python manage.py makemigrations
Если всё прошло успешно, вы увидите что-то вроде:
Migrations for 'app_name':
app_name/migrations/0001_initial.py
- Create model MyModel
Что здесь произошло?
- Миграция
0001_initial.pyсоздана для приложенияapp_name. - Django автоматически сгенерировал файл миграции с инструкцией для создания модели
MyModel.
python manage.py migrate
Эта команда применяет миграции к базе данных. По сути, она отправляет SQL-запросы, которые создают таблицы, добавляют или изменяют поля.
Пример:
$ python manage.py migrate
Вы увидите вывод, показывающий успешное выполнение миграций:
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying app_name.0001_initial... OK
python manage.py showmigrations
Эта команда позволяет посмотреть список существующих миграций и их статус (применены ли они к базе данных).
Пример:
$ python manage.py showmigrations
Результат может быть таким:
admin
[X] 0001_initial
auth
[X] 0001_initial
app_name
[ ] 0001_initial
В данном примере:
[X]означает, что миграция была применена.[ ]означает, что миграция ещё не была применена.
Практика: Создание миграций
Давайте создадим модель и посмотрим, как она превращается в миграцию, а затем в таблицу базы данных.
Шаг 1: создание модели
Мы добавим модель для хранения информации о книгах (название, автор и дата публикации). Добавьте следующий код в файл models.py приложения:
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100)
published_date = models.DateField()
is_available = models.BooleanField(default=True)
def __str__(self):
return self.title
Шаг 2: генерация миграции
Теперь создадим миграцию с помощью команды makemigrations:
$ python manage.py makemigrations
Вы увидите, что Django создал миграцию для модели Book.
Шаг 3: просмотр созданной миграции
Заглянем в файл миграции. Он будет находиться в папке migrations вашего приложения (например, my_app/migrations/0001_initial.py):
# Generated by Django X.Y on YYYY-MM-DD HH:MM
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Book',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=100)),
('author', models.CharField(max_length=100)),
('published_date', models.DateField()),
('is_available', models.BooleanField(default=True)),
],
),
]
Здесь вы видите, как модель Book интерпретируется в SQL-команды для создания таблицы.
Шаг 4: применение миграции
Теперь применим миграцию с помощью команды migrate:
$ python manage.py migrate
Вывод покажет, что таблица Book успешно создана.
Изменение моделей и работы с миграциями
Иногда нужно внести изменения в модель, например, добавить новое поле или изменить тип данных. Давайте разберём типичный сценарий.
Шаг 1: изменение модели
Добавим поле genre к нашей модели Book:
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100)
published_date = models.DateField()
is_available = models.BooleanField(default=True)
genre = models.CharField(max_length=50, default='Fiction') # Новое поле
Шаг 2: создание новой миграции
Снова используем команду makemigrations:
$ python manage.py makemigrations
Дjango создаёт новую миграцию, которая добавляет поле genre к таблице Book.
Шаг 3: применение миграции
Применяем изменения к базе данных:
$ python manage.py migrate
Теперь таблица Book обновлена с новым полем genre.
Обратные миграции: "Ой, я ошибся"
Что если вы случайно сделали неправильную миграцию? Спокойно, у Django есть способ "откатить" миграции.
Команда migrate <app_name> <migration_name>
Чтобы откатить миграцию, укажите имя приложения и миграцию, до которой нужно вернуться.
Пример:
$ python manage.py migrate app_name 0001
Это вернёт состояние базы данных к миграции 0001, удаляя последующие изменения.
Типичные ошибки и подводные камни
- Не забывайте сохранять модели перед
makemigrations. Если изменения не сохранены, Django не увидит их. - Работа с реальными данными требует осторожности. Убедитесь, что новая структура не ломает существующих данных.
- Поле требует значения, но данные уже есть. Если вы добавляете обязательное поле
null=Falseк модели с существующими данными, добавьте атрибутdefault, иначе возникнет ошибка. - Удаление полей. Если вы удаляете поле из модели, будьте внимательны: все данные в этом поле будут удалены.
Миграции — это сердце вашей базы данных, и всё, что вы делаете с Django ORM, однажды окажется у миграций "на столе". Поэтому берегите их, и они будут беречь вашу базу данных.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ