当使用带有参数元组的execute语句从值列表中进行批量更新数据时,值列表中的null值被视为数据类型varchar列,例如,双重精度。一个例子是:
create table mytable (mykey varchar, myvalue double precision);
cur.execute("""update mytable t set (myvalue)=(v.myvalue) from (values %s, %s) v (mykey, myvalue) where t.mykey = v.mykey""", ([('key1', None),('key2', None)]))
此查询的错误是:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
psycopg2.ProgrammingError: column "myvalue" is of type double precision but expression is of type text
LINE 1: update mytable t set (myvalue)=(v.myvalue) from (values ('ke...
^
HINT: You will need to rewrite or cast the expression.
如何在值列表中指定null值的数据类型?
指令很明确。您需要施放值:
. . .
set myvalue = (v.myvalue::double precision)
问题是null
是无类型的,但是列必须具有类型。Postgres选择最通用的类型,您需要明确的转换回一个数字。
您要么在@gordon答案中以 set
子句施放它,要么给它一个数据类型提示在第一个值元组上:
query = '''
update mytable t
set myvalue = v.myvalue
from (values ('impossible key', 1.0), %s, %s) v (mykey, myvalue)
where t.mykey = v.mykey
'''
data = [('key1', None),('key2', None)]
cursor.execute(query, data)