[英]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.