0

sqlalchemy-migrate を使用して、Postgre SQL データベースのテーブルの列の 1 つの型を変更しています。私が使用しているアップグレードスクリプトは次のとおりです。

# -*- 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::numericALTERに含める方法はありますか? または、上に投稿したエラーを回避する別の方法はありますか?

私はあなたの助けに感謝します。

4

1 に答える 1

5

sqlalchemy.migrate は、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')

ところで、文字列から整数への移行は、さまざまな理由で失敗する可能性があります-列の値に数値に変換できない値が含まれている場合。そのため、アプリケーション ロジックに追加の検証を追加して、後でダウングレード移行を可能にします。

于 2013-03-06T17:17:33.697 に答える