首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >需要PyGreSQL upsert()帮助

需要PyGreSQL upsert()帮助
EN

Stack Overflow用户
提问于 2021-06-11 02:49:21
回答 1查看 26关注 0票数 0

我在Python3.8、PostgreSQL 12和PyGreSQL 5.2.2上使用CentOS-6。

对于较旧的版本,我有一个如下所示的函数。当时,如果行不存在,update将引发异常,因此在出现异常时,我将插入数据行。

代码语言:javascript
复制
import pg
db = pg.DB(myDatabaseName, myport)
try:
   db.update(tableName, None, **rowData)
except:
   db.insert(tableName, None, **rowData)

在我现在使用的版本中,如果行不存在,更新不会引发异常,因此我的代码不再正常工作。我正在尝试使用upsert来替换该功能,但遇到了问题。

我的表有50列。名为phy的1列是主键。

我认为下面的upsert命令会更新我在rowData变量中传递的列的值,而不会影响其他列。在这个主键没有一行数据的情况下,它将插入新的一行数据。

代码语言:javascript
复制
rowData = {'phy': 1234, 'col2': 'test', 'col3': 'test'}
db.upsert(tableName, rowData)

upsert方法将更新表中的每一列。它执行的命令如下所示:

代码语言:javascript
复制
INSERT INTO tableName AS included ('phy', 'col2', col3') VALUES (1234, 'test', 'test) ON CONFLICT (phy) DO update set "col4" = excluded."col4", "col5"=excluded."col5" etc with all 50 columns listed here

有没有办法将upsert方法配置为只更新传入的列的值?如果不是,那么替换原始更新或插入功能的最佳方式是什么?

如有任何帮助,我们不胜感激!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-11 20:25:51

关于你的第一个代码片段,如果你反其道而行之,它应该可以工作:

代码语言:javascript
复制
try:
    db.insert(tableName, None, **rowData)
except pg.IntegrityError:
    db.update(tableName, None, **rowData)

您还可以简化此操作:

代码语言:javascript
复制
try:
    db.insert(tableName, rowData)
except pg.IntegrityError:
    db.update(tableName, rowData)

也许这与使用OID进行更新的旧PostgreSQL版本的行为有所不同。

关于upsert特性,我认为你是对的-在字典没有包含所有列的情况下,它不会像预期的那样工作。我已经提交了一份issue,并提出了改进建议。

作为一种变通方法,在这个问题得到解决之前,您可以通过upsert()方法的关键字显式地声明哪些列应该更新。所以你可以这样做:

代码语言:javascript
复制
rowData = {'phy': 1235, 'col2': 'test2', 'col3': 'test3'}
kw = {n: n in rowData for n in db.get_attnames(tableName)}
db.upsert(tableName, rowData, **kw)

也就是说,您传递一个字典,该字典具有不属于指定rowData的列的False值。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67926936

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档