Рубрики
Без рубрики

Alembic: настройка столбца на Если в нем уже есть данные

Alembic-отличный способ автоматического управления вашей базой данных SQL через код Python в вашем git Repo … Tagged с Python, SQL, базой данных.

Alembic-отличный способ автоматического управления вашей базой данных SQL через код Python в вашем репозитории GIT. Вместо того, чтобы вручную вносить правильные изменения вручную в базе данных каждый раз, когда вы обновляете свой код, вы можете сохранить обновления базы данных как часть вашей кодовой базы: Alembic может автоматически генерировать эти сценарии обновления, сравнивая текущую структуру вашей базы данных с тем, что они должен быть в соответствии с вашей схемой ORM (SQLALCHEMY).

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

Тем не менее, одна область, где автогенератор Алембика не совсем понимается, – это то, как справиться с установкой поля из Nullable = Верно к Nullable = Ложный Когда в столбце уже есть нулевые значения. Автогенератор покорно создаст сценарий, который обновляет свойство столбца, которое содержит это:

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.alter_column('table_name', 'column_name',
               existing_type=sa.VARCHAR(),
               nullable=False,
               schema='schema_name')
    # ### end Alembic commands ###

Но, поскольку он не может волновать все существующие нули в базе данных, база данных отклонит это изменение, поскольку оно оставит нули внутри столбца, который не является нулевым. Сообщение об ошибке в основном «столбец содержит нулевые значения»:

sqlalchemy.exc.ProgrammingError: (pg8000.exceptions.ProgrammingError) {'S': 'ERROR', 'V': 'ERROR', 'C': '23502', 'M': 'column "column_name" contains nu
ll values', 's': 'acquire', 't': 'table_name', 'c': 'column_name', 'F': 'tablecmds.c', 'L': '4858', 'R': 'ATRewriteTable'}
[SQL: ALTER TABLE schema_name.table_name ALTER COLUMN column_name SET NOT NULL]

Чтобы решить это, вы должны сначала избавиться от всех нулей, которые, если вы не хотите делать это вручную в базе данных, также может быть сделано путем редактирования сценария с автогенерированием, чтобы справиться с этим. Самый простой способ – добавить op.execute () Это обновит нулевые значения до чего -то другого. Что-то вроде этого:

def upgrade():
    table_name = sa.sql.table("table_name", sa.Column("column_name", sa.VARCHAR()), schema="schema_name")
    op.execute(
        table_name.update()
        .where(table_name.c.column_name is None)
        .values(column_name="some_value")
    )
    op.alter_column('table_name', 'column_name',
               existing_type=sa.VARCHAR(),
               nullable=False,
               schema='schema_name')

Здесь op.execute устанавливает гипотетический столбец, называемый column_name иметь значение «some_value», если он в настоящее время нуль. Таким образом, обеспечение отсутствия значений в столбце все еще остается нулевым к тому времени, когда OP.Alter_column устанавливает Nullable ограничение ложным.

Во всех вышеперечисленных коде это было в базе данных Postgres со схемой без декорации, называемой schema_name Анкет Для использования схемы по умолчанию или базам данных без схемы, этого должно быть достаточно, чтобы опустить схема = Везде это кажется.

Оригинал: “https://dev.to/meseta/alembic-setting-a-column-to-nullable-true-if-it-already-has-data-in-it-3nb7”