繁体   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