Как изменить тип столбца с изменяющегося символа на целое с помощью sqlalchemy-migrate

Я использую sqlalchemy-migrate, чтобы изменить тип одного из столбцов в таблице в базе данных Postgre SQL. Сценарий обновления, который я использую:

# -*- cofing: utf-8 -*-

from sqlalchemy import MetaData, Table, Column, String, Integer
from migrate import changeset


metadata = MetaData()


def upgrade(migrate_engine):
    # ALTER TABLE courses ALTER COLUMN number SET DATA TYPE character varying;
    metadata.bind = migrate_engine
    courses = Table('courses', metadata, Column("number", Integer), extend_existing=True)
    courses.c.number.alter(type=String)


def downgrade(migrate_engine):
    # ALTER TABLE courses ALTER COLUMN number SET DATA TYPE integer;
    metadata.bind = migrate_engine
    courses = Table('courses', metadata, Column("number", String), extend_existing=True)
    courses.c.number.alter(type=Integer, cast='numeric')

Часть обновления, кажется, работает, но обновление всегда завершается с ошибкой:

sqlalchemy.exc.ProgrammingError: (ProgrammingError) column "number" cannot be cast to type integer
'\nALTER TABLE courses ALTER COLUMN number TYPE INTEGER' {}

Теперь, если бы я использовал простой SQL, я мог бы использовать ALTER TABLE courses ALTER COLUMN number TYPE INTEGER USING number::numeric изменить тип столбца обратно из character varying в integer, но я не знаю, как добиться этого с помощью sqlalchemy-migrate.

Есть ли способ заставить sqlalchemy включить USING number::numeric в ALTER статья? или есть другой способ избежать ошибки, которую я выложил выше?

Я ценю вашу помощь.

1 ответ

Решение

Похоже, sqlalchemy.migrate не поддерживает отображение правильного запроса в случае изменения типов столбца String на Integer для postgresql.

В вашем случае я бы реализовал это как прямое выполнение запроса и пошел дальше.

def downgrade(migrate_engine):
    # ALTER TABLE courses ALTER COLUMN number SET DATA TYPE integer;
    migrate_engine.execute('ALTER TABLE courses ALTER COLUMN number TYPE INTEGER USING number::numeric')

Кстати, миграция из String в Integer может завершиться неудачей по разным причинам - когда значение столбца будет содержать некоторое значение, которое не может быть преобразовано в число. Поэтому я хотел бы добавить дополнительную проверку в логику приложения, чтобы впоследствии можно было выполнить переход на более раннюю версию.

Другие вопросы по тегам