使用 on_conflict_do_update 在 upsert 中添加列

问题描述 投票:0回答:1

我尝试在使用 on_conflict_do_update 执行更新插入时在更新中添加时间戳列 Updated_at。以下是我当前的实现,但在最后一行运行时遇到以下错误。

发生异常:ProgrammingError (psycopg2.errors.AmbigouslyColumn) 列引用“updated_at”不明确 第 1 行:...r,properties = excepted.properties,updated_at = Updated_at

知道如何实现吗?

def postgres_upsert(table, conn, keys, data_iter):
    from sqlalchemy.dialects.postgresql import insert

    data = [dict(zip(keys, row)) for row in data_iter]

    insert_statement = insert(table.table).values(data)

    x = {c.key: c for c in insert_statement.excluded}
    x["updated_at"] = Column('updated_at', TIMESTAMP, default=datetime.datetime.now())

    upsert_statement = insert_statement.on_conflict_do_update(
        constraint=f"{table.table.name}_pkey",
        # set_={c.key: c for c in insert_statement.excluded},
        set_=x,
    )
    conn.execute(upsert_statement)
python pandas postgresql sqlalchemy upsert
1个回答
0
投票

如果通过添加列您的意思是,冲突解决条款,它已经为您完成了

特殊别名

Insert.excluded

 可用作 Insert 对象的属性;该对象是一个 
ColumnCollection
,其别名 
包含目标表的所有列

如果该表有

updated_at

,则您已经使用 
x = {c.key: c for c in insert_statement.excluded}
 以及所有其他表处理了它。

如果表格没有

updated_at

 并且您的字面意思是您希望 
添加一个全新的列,则必须 alter
 表格,我认为更新插入不是一个好地方这样做。

另一种猜测是您尝试使用

updated_at

 列的 
default
now()
,而不是表中当前的任何内容,同时忽略 
excluded.updated_at
 下的任何内容。您可以将其作为来自应用程序的文字传递:

x["updated_at"] = datetime.datetime.now()

db 的 now()


x["updated_at"] = func.now()
    
© www.soinside.com 2019 - 2024. All rights reserved.