🔗 Миграции БД | Tooling


References


Достоинства

  • Простое внедрение, работа с SQLAlchemy.
  • Автоматическая генерация кода миграций на основе ORM-моделей.
  • Возможность использования Python внутри кода с миграциями.
  • Фиксация миграций в отдельной таблице alembic_version.

Недостатки

  • Не фиксирует изменения имён таблиц и имён колонок (проверить в актуальной версии!)

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

Инициализация – создаст директорию ./alembic/ и файл ./alembic.ini:

alembic init alembic

Как настроить с SQLModel – см. на TestDriven.

Далее, в файле alembic.ini необходимо указать корректное подключение к БД в параметре sqlalchemy.url. Для Postgres используем postgres://, без asyncpg. Там же прописать prepend_sys_path = .., чтобы при запуске кода ниже нашелся модуль app. (Это не надо делать, если выполнять команду ниже из папки, где лежит alembic.ini).

В файле ./alembic/env.py, там где # for 'autogenerate' support, прописать что-то типа:

from app import Base
target_metadata = Base.metadata

Делаем первую миграцию. Для создания миграции, должно быть возможно соединение с БД, указанной в настройках!

alembic revision --message="Init migration" --autogenerate

В директории ./alembic/versions/ повится .py-файл миграции.

Чтобы применить созданную миграцию, нужно выполнить:

alembic upgrade head

Идентификатор последней примененной миграции будет в БД в таблице alembic_version.

Чтобы откатиться, используем команду:

alembic downgrade <current_revision_id>-1

Если есть несколько “параллельных” миграций (например, от разных разработчиков при совместной разработке), их необходимо объединить командой:

alembic merge heads -m "Merge migrations ... ... ..."

Создастся ещё одна миграция для слияния параллельных веток. После этого, можно применить команду alembic upgrade head.

Добавляем NON-NULL поле в заполненную таблицу

Используем следующий трюк в миграции:

from typing import Sequence, Union
 
import sqlalchemy as sa
import sqlmodel
from alembic import op
 
# revision identifiers, used by Alembic.
revision: str = "fc274cf576c2"
down_revision: Union[str, None] = "cbd0bc20cc4c"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
 
 
def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column(
        "profiles",
        sa.Column[[(]]
            "platform",
            sqlmodel.sql.sqltypes.AutoString(),
            nullable=True,
        ),
    )
    # 
    # Временно делаем поле nullable, заполняем его чем-то, и потом
    # возвращаем nullable=False выше. После применения этой миграции,
	# удалить две следующие строки.
    #
    op.execute("UPDATE profiles SET platform = 'telegram'")
    op.alter_column("profiles", "platform", nullable=False)
    # ### end Alembic commands ###
 
 
def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column("profiles", "platform")
    # ### end Alembic commands ###

📂 Tooling | Последнее изменение: 11.08.2024 09:08