Skip to main content

Библиотека SQL-миграций для баз данных. Миграции — это обычные .sql файлы.

Требования

  • Python >= 3.10.

  • Драйвер целевой СУБД (см. таблицу ниже). Для SQLite ничего дополнительно устанавливать не нужно — используется модуль стандартной библиотеки sqlite3.

Установка

Базовый пакет (включает только поддержку SQLite):

pip install classic-migrations

Поддержка конкретных СУБД подключается опциональными зависимостями (extras):

СУБД

extra

драйвер (значение DATABASE_DRIVER)

SQLite

sqlite3

PostgreSQL

postgres

psycopg

MySQL

mysql

pymysql

Oracle

oracle

oracledb

Microsoft SQL Server

pymssql

pymssql

pip install classic-migrations[postgres]
pip install classic-migrations[mysql]

Или через uv:

uv add classic-migrations
uv add "classic-migrations[postgres]"

Пакет предоставляет исполняемую команду migrations:

migrations --help

Настройка

Все настройки читаются из переменных окружения или из .env файла в текущем каталоге. Переменные окружения имеют приоритет над значениями из .env.

Пример .env:

# каталоги с файлами миграций, разделённые двоеточием
SOURCES=./migrations

# имя таблицы истории (опционально, по умолчанию "migrations")
MIGRATIONS_TABLE=migrations

# настройки подключения к базе данных
DATABASE_DRIVER=sqlite3
DATABASE_USER=
DATABASE_USER_DOMAIN=
DATABASE_PASSWORD=
DATABASE_HOST=
DATABASE_PORT=
DATABASE_NAME=./db.sqlite

Если задан DATABASE_USER_DOMAIN, то имя пользователя формируется как DOMAIN\USER.

Полный список настроек:

Переменная

Назначение

Значение по умолчанию

SOURCES

пути к каталогам миграций, разделённые двоеточием

(пусто)

DATABASE_DRIVER

имя модуля драйвера подключения (sqlite3, psycopg, pymysql, oracledb, pymssql)

(пусто)

DATABASE_USER

имя пользователя БД

(пусто)

DATABASE_USER_DOMAIN

домен пользователя БД (опционально)

(пусто)

DATABASE_PASSWORD

пароль

(пусто)

DATABASE_HOST

хост

(пусто)

DATABASE_PORT

порт (преобразуется в целое число)

(пусто)

DATABASE_NAME

имя БД (или путь к файлу для SQLite)

(пусто)

MIGRATIONS_TABLE

имя таблицы истории

migrations

MIGRATIONS_SCHEMA

схема, в которой размещается таблица истории (игнорируется для БД без поддержки схем)

(пусто)

OLD_MIGRATIONS_SCHEMA

схема legacy-таблицы versions (yoyo-migrations)

(пусто)

Файлы миграций

Миграция — это .sql файл в каталоге миграций. Имя файла (без расширения) становится идентификатором миграции.

В начальном комментарии файла можно указать директивы:

-- depends: 20260821_01_init, 20260822_02_users
-- transactional: true

CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);

Директивы:

  • -- depends: <id>, <id>, ... — список миграций, от которых зависит текущая, через запятую. Имена должны соответствовать реальным миграциям, иначе выбрасывается исключение NoMigration;

  • -- transactional: true|false — выполнять ли миграцию в транзакции (по умолчанию true; если не указано — поведение определяется возможностями СУБД).

Для отката миграции используется файл <имя>.rollback.sql — имя с вставкой .rollback перед расширением, размещённый рядом с основной миграцией. У rollback-файла допускается только директива -- transactional.

Хуки

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

  • pre-apply.sql — выполняется перед применением набора миграций;

  • post-apply.sql — после применения набора миграций;

  • pre-rollback.sql — перед откатом набора миграций;

  • post-rollback.sql — после отката набора миграций.

Команды

Доступные команды: list, apply, rollback.

Общий параметр, принимаемый всеми командами:

  • -v — увеличить подробность вывода. Можно повторять: -v → WARNING, -vv → INFO, -vvv → DEBUG (по умолчанию ERROR).

list

Показывает миграции источника и их статус в текущей БД:

migrations list
  • --history — показать только применённые миграции.

apply

Применяет неприменённые миграции (в топологическом порядке):

migrations apply [migration_name]
  • migration_name — позиционный необязательный аргумент: применить миграции до указанной включительно; без него — все доступные;

  • --fake — только создать записи в истории, без выполнения SQL миграций и хуков;

  • --plan — не применять миграции, а только вывести список тех, которые можно применить к текущей БД.

rollback

Откатывает применённые миграции (в обратном топологическом порядке):

migrations rollback [migration_name]
  • migration_name — позиционный необязательный аргумент: откатить миграции до указанной включительно; без него — все применённые;

  • --fake — только создать записи в истории, без выполнения SQL отката и хуков;

  • --plan — не откатывать миграции, а только вывести список тех, которые можно откатить в текущей БД.

Если у миграции нет .rollback.sql файла, при откате записывается только событие ROLLED_BACK в историю — SQL не выполняется.

Использование как библиотеки

Публичный API:

from classic.migrations import (
    BadConnectionURI,
    BadMigration,
    InvalidArgument,
    MigrationConflict,
    MigrationLockError,
    MigrationsCollection,
    Migrator,
    NoMigration,
)

MigrationsCollection работает только с источниками миграций (каталогами .sql файлов) и не имеет доступа к БД:

  • MigrationsCollection(sources)sources — путь к каталогу миграций (строка) или список путей. Читает миграции и хуки один раз и переиспользует их при последующих вызовах;

  • list() — список миграций источника, отсортированный топологически;

  • to_apply(history, target=None) — по логу событий истории вычисляет применённые и возвращает (hooks, migrations): хуки и неприменённые миграции в топологическом порядке; target — «до указанной включительно»;

  • to_rollback(history, target=None) — аналогично, но возвращает применённые миграции в обратном топологическом порядке;

  • applied_ids(history) — статический метод: возвращает множество id миграций, чей последний статус в истории — APPLIED.

Migrator принимает параметры БД, выбирает Backend по имени драйвера и выполняет миграции (сам не содержит SQL). Параметры конструктора:

  • driver — имя модуля драйвера (sqlite3, psycopg, pymysql, oracledb, pymssql);

  • db_host, db_port, db_name, db_user, db_pass — параметры подключения;

  • migration_table='migrations' — имя таблицы истории;

  • migration_schema=None — схема таблицы истории;

  • versions_schema=None — схема legacy-таблицы versions.

Migrator — контекстный менеджер: при входе устанавливает соединение и берёт advisory-lock, при выходе закрывает соединение. Методы должны вызываться только внутри with:

  • history() — лог событий таблицы истории (список кортежей (migration_id, created_at, status));

  • apply(migrations, hooks, fake=False) — применяет миграции; fake=True — только записи в истории, без SQL и хуков;

  • rollback(migrations, hooks, fake=False) — откатывает миграции (аналогично apply);

  • close() — закрывает соединение (обычно не нужен — соединение закрывается при выходе из with).

Применение миграций:

from classic.migrations import Migrator, MigrationsCollection

db = Migrator(
    driver='psycopg',
    db_host='localhost',
    db_port=5432,
    db_name='tests',
    db_user='test',
    db_pass='test',
)
migrations = MigrationsCollection('./migrations')

with db:
    history = db.history()
    hooks, unapplied = migrations.to_apply(history)
    db.apply(unapplied, hooks)

Откат миграций:

with db:
    history = db.history()
    hooks, applied = migrations.to_rollback(history)
    db.rollback(applied, hooks)

Схема таблицы истории

Библиотека создаёт одну служебную таблицу — append-only лог событий:

CREATE TABLE {migration_table} (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    migration_id VARCHAR(255) NOT NULL,
    created_at   TIMESTAMP NOT NULL,
    status       VARCHAR(16) NOT NULL  -- 'APPLIED' | 'ROLLED_BACK' | 'PENDING'
);

Каждое применение или откат миграции дописывает строку-событие. Актуальный статус миграции определяется её последним событием. Сверка хешей применённых миграций не выполняется.

Для нетранзакционных СУБД запись в историю производится до применения (статус PENDING), а после успешного выполнения — APPLIED.

При первом запуске данные из legacy-таблицы versions (yoyo-migrations) переносятся как события APPLIED; сама таблица не удаляется.

Особенности бэкендов

Oracle

Бэкенд Oracle берёт advisory-lock через SYS.DBMS_LOCK.REQUEST. Пользователю, под которым выполняются миграции, необходимо право EXECUTE на SYS.DBMS_LOCK; без него вход в with migrator: завершится ошибкой MigrationLockError.

В контейнерных образах gvenzl/oracle-* это право выдаётся скриптом инициализации docker/oracle-init/01_grant_dbms_lock.sql. Локально он монтируется в /container-entrypoint-initdb.d (см. docker-compose.yml) и выполняется при первом старте контейнера. В CI (job test-oracle в .github/workflows/test.yml) скрипт выполняется после checkout через docker exec, поскольку сервис-контейнеры GitHub Actions стартуют до checkout и не позволяют смонтировать каталог из репозитория.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

classic_migrations-2.0.1.tar.gz (36.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

classic_migrations-2.0.1-py3-none-any.whl (36.8 kB view details)

Uploaded Python 3

File details

Details for the file classic_migrations-2.0.1.tar.gz.

File metadata

  • Download URL: classic_migrations-2.0.1.tar.gz
  • Upload date:
  • Size: 36.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for classic_migrations-2.0.1.tar.gz
Algorithm Hash digest
SHA256 19c1ebd87d35c15b77b31c80299b87407727b5ef198364ccd5d70a7b00204938
MD5 dec444452211441b5ab57fba240b02f5
BLAKE2b-256 9f6a9b4fe3bf1c71857cce99c2406fe387969f8d2ba967f57a0120c861c87e39

See more details on using hashes here.

Provenance

The following attestation bundles were made for classic_migrations-2.0.1.tar.gz:

Publisher: publish.yml on variasov/classic-migrations

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file classic_migrations-2.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for classic_migrations-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 df40b3b0257541154cbd9041446c3fdcdb255d2b4e9a858a462110deac53be6b
MD5 be0a30f94da4084026bcb3b8c5a99497
BLAKE2b-256 755c1a6a864d511e408feb3ee9226a06f6729aaad6e3463d20c906208aee3120

See more details on using hashes here.

Provenance

The following attestation bundles were made for classic_migrations-2.0.1-py3-none-any.whl:

Publisher: publish.yml on variasov/classic-migrations

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

2.0.1 This release

2 files

2.0.0

2 files

0.0.17

2 files

0.0.16

2 files

0.0.15

1 file

0.0.14

1 file

0.0.13

1 file

0.0.12

2 files

0.0.11

2 files

0.0.10

2 files

0.0.8

2 files

0.0.7

2 files

0.0.6

2 files

0.0.5

2 files

0.0.4

2 files

0.0.3

2 files

0.0.2

1 file

0.0.1

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page