簡體   English   中英

嘗試更新列時,Alembic 遷移服務器默認值被識別為 null

[英]Alembic migration server default value is recognized as null when trying to update a column

我正在嘗試進行遷移以根據has_bubble_in_countries的列值更新has_bubble_v1列的值。

我在upgrade()之前創建了表:

subscription_old_table = sa.Table(
        'Subscription',
        sa.MetaData(),
        sa.Column('id', sa.Unicode(255), primary_key=True, unique=True, nullable=False),
        sa.Column('has_bubble_v1', sa.Boolean, nullable=False, default=False),
        sa.Column('has_bubble_in_countries', MutableList.as_mutable(ARRAY(sa.Enum(Country))), nullable=False, default=[], server_default='{}')
    )

然后upgrade()方法如下所示:

def upgrade():

    connection = op.get_bind()

    for subscription in connection.execute(subscription_old_table.select()):
        if subscription.has_bubble_v1:
            connection.execute(
                subscription_old_table.update().where(
                    subscription_old_table.c.id == subscription.id
                ).values(
                    has_bubble_in_countries=subscription.has_bubble_in_countries.append(Country.NL),
                )
            )
    # Then drop the column after the data has been migrated
    op.drop_column('Subscription', 'has_bubble_v1')

當我使用 pgadmin 的界面檢查數據庫時, has_bubble_in_countries列數據庫中的所有行都具有此值 {}。

upgrade() function 到達更新方法時,它會拋出此錯誤:

sqlalchemy.exc.IntegrityError: (psycopg2.errors.NotNullViolation) null value in column "has_bubble_in_countries" of relation "Subscription" violates not-null constraint
DETAIL:  Failing row contains (keydsakwlkad, null, 2027-08-14 00:00:00+00,groot abonnement, big, {nl}, null, null, 2022-08-08 08:45:52.875931+00, 3482992, {}, f, null, null, null, t, 2011-05-23 08:55:20.538451+00, 2022-08-08 09:10:15.577283+00, ***null***).

[SQL: UPDATE "Subscription" SET has_bubble_in_countries=%(has_bubble_in_countries)s::country[] WHERE "Subscription".id = %(id_1)s]
[parameters: {'has_bubble_in_countries': None, 'id_1': '1pwohLmjftAZdIaJ'}]

錯誤中的粗體值是為has_bubble_in_countries列檢索的值,即使它具有server_default='{}'nullable=False也是如此。

是否有可能向 alembic 添加配置以在從數據庫檢索時識別服務器默認值? 或者如何解決?

我認為問題實際上是你傳遞的.append()的結果是 None。 與通常返回更改后的列表的其他語言不同,append 會原地更改列表。 我不確定這對於此處的核心查詢結果是否是個好主意,但它似乎有效。

with Session(engine) as session, session.begin():

    for subscription in session.execute(subscription_old_table.select()):
        if subscription.has_bubble_v1:
            # Append here.
            subscription.has_bubble_in_countries.append(Country.NL)
            # Then set values:
            session.execute(
                subscription_old_table.update().where(
                    subscription_old_table.c.id == subscription.id
                ).values(has_bubble_in_countries=subscription.has_bubble_in_countries,
                )
            )

也許克隆列表然后像這樣添加元素會更安全、更清晰:

has_bubble_in_countries=subscription.has_bubble_in_countries[:] + [Country.NL]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM