Какую роль играют операции (Operations) в миграциях Django?

Ответ

В системе миграций Django Operation — это класс, представляющий одно атомарное изменение схемы базы данных. Миграции состоят из списка таких операций, которые Django выполняет последовательно.

Основное назначение операций — обеспечить декларативность и независимость от СУБД. Вместо того чтобы писать SQL-запросы вручную, вы описываете что нужно сделать (создать модель, добавить поле), а Django сам генерирует корректный SQL для конкретной базы данных (PostgreSQL, MySQL, SQLite и т.д.).

Пример файла миграции:

# 0002_auto_20231027_1200.py
from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0001_initial'),
    ]

    # Список операций, которые будут выполнены
    operations = [
        migrations.AddField(
            model_name='author',
            name='email',
            field=models.EmailField(max_length=254, unique=True, default=''),
            preserve_default=False,
        ),
        migrations.CreateModel(
            name='Book',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)),
                ('title', models.CharField(max_length=200)),
            ],
        ),
    ]

Наиболее распространенные операции:

  • CreateModel: Создает новую таблицу в БД.
  • DeleteModel: Удаляет таблицу.
  • AddField: Добавляет новый столбец в таблицу.
  • RemoveField: Удаляет столбец.
  • AlterField: Изменяет параметры существующего столбца.
  • RenameModel / RenameField: Переименовывает таблицу или столбец.
  • RunPython: Выполняет произвольный Python-код (для миграций данных).
  • RunSQL: Выполняет произвольный SQL-запрос.

Ответ 18+ 🔞

Давай разберёмся, что это за зверь такой — Operation в миграциях Django. Представь себе, что ты не строитель, который сам таскает кирпичи и мешает бетон, а архитектор, который рисует чертёж: «здесь будет стена, здесь — окно». Так вот, Operation — это и есть одна такая команда на чертеже: «поставь стену», «проруби окно». А Django — это прораб, который смотрит на твой чертёж и уже сам командует рабочим-СУБД: «Вася, на PostgreSQL стену ставь вот так, а на SQLite — вот эдак, и не спорь!».

Смысл всего этого цирка — чтобы ты не парился с SQL вручную. Ты просто пишешь на Питоне, что хочешь сделать, а Django уже сам соображает, как это сделать на твоей конкретной базе данных. Независимость от СУБД, ёпта! Одна и та же операция AddField на PostgreSQL превратится в ALTER TABLE ... ADD COLUMN ..., а на SQLite — в целую хуету с созданием новой таблицы и копированием данных, потому что SQLite — тот ещё геморрой с изменением схемы.

Вот смотри, как это выглядит в живой миграции:

# 0002_auto_20231027_1200.py
from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0001_initial'),
    ]

    # А вот и наш список команд для прораба
    operations = [
        migrations.AddField( # Команда №1: «Добавь колонку»
            model_name='author',
            name='email',
            field=models.EmailField(max_length=254, unique=True, default=''),
            preserve_default=False,
        ),
        migrations.CreateModel( # Команда №2: «Построй новую таблицу»
            name='Book',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)),
                ('title', models.CharField(max_length=200)),
            ],
        ),
    ]

Какие бывают эти самые операции-команды? Самые ходовые:

  • CreateModel — «Создай новую таблицу, блядь». Самая первая операция обычно.
  • DeleteModel — «Таблицу эту — нахуй». Когда модель удаляешь.
  • AddField — «Добавь ещё один столбик в таблицу». Самый частый гость.
  • RemoveField — «А этот столбик — удали». Обратное действие.
  • AlterField — «Слушай, а давай-ка мы поменяем у этого столбца максимальную длину...». Изменение параметров.
  • RenameModel / RenameField — «Переименуй таблицу/столбец, а то название кривое». Осторожно, SQLite опять обосрётся.
  • RunPython — «А тут, сука, надо данные подправить, SQL-ем не обойдёшься». Для кастомной логики на Питоне.
  • RunSQL — «Всё, прораб, отойди, я сам всё сделаю!». Когда ты знаешь точный SQL и хочешь выебать систему по-своему. Ответственность — полностью на тебе, в рот меня чих-пых.

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