我们需要对Postgres DB中的许多行进行批量更新,并希望使用下面的SQL语法。
UPDATE table_to_be_updated
SET msg = update_payload.msg
FROM (VALUES %(update_payload)s) AS update_payload(id, msg)
WHERE table_to_be_updated.id = update_payload.id
RETURNING *
尝试1 -传递值
我们需要向psycopg 2查询传递一个嵌套的可迭代格式,对于update_payload
,我尝试过传递列表的列表、元组的列表和元组的元组,但都失败了,出现了各种错误。
尝试2 -使用__conform__编写自定义类
我试着编写一个自定义类来执行这些操作,它将返回
(VALUES (row1_col1, row1_col2), (row2_col1, row2_col2), (...))
我按照这里的说明编写了这样的代码,但很明显我做错了什么,例如,在这种方法中,我必须处理表中所有值的引用,这会很麻烦,而且容易出错。
class ValuesTable(list):
def __init__(self, *args, **kwargs):
super(ValuesTable, self).__init__(*args, **kwargs)
def __repr__(self):
data_in_sql = ""
for row in self:
str_values = ", ".join([str(value) for value in row])
data_in_sql += "({})".format(str_values)
return "(VALUES {})".format(data_in_sql)
def __conform__(self, proto):
return self.__repr__()
def getquoted(self):
return self.__repr__()
def __str__(self):
return self.__repr__()
**编辑:**如果使用另一种语法可以更快/更干净地完成批量更新,而不是我最初的问题,那么我洗耳恭听!
2条答案
按热度按时间mwyxok5s1#
要求:
假设的,自包含的例子程序与报价的一个著名的物理学家。
上述程序将向调试控制台输出以下内容:
bbuxkriu2#
简短答案!使用
execute_values(curs, sql, args)
,请参阅文档对于那些寻找简单明了的答案。示例代码批量更新用户;
如果你使用
uuid
作为主键,并且还没有在psycopg 2中注册uuid数据类型(将uuid保存为python字符串),你可以使用u.id = t.id::uuid
这个条件。