从具有空值

时间:2016-12-18 16:53:02

标签: postgresql list null psycopg2

当使用带有参数元组的execute语句从值列表批量更新数据时,值列表中的空值被视为数据类型varchar,因此在插入非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.

如何在值列表中指定空值的数据类型?

2 个答案:

答案 0 :(得分:1)

说明很清楚。您需要转换值:

. . .
set myvalue = (v.myvalue::double precision)

问题是null是无类型的,但列必须有类型。 Postgres选择最常规的类型,您需要显式转换回数字。

答案 1 :(得分:1)

要么像@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)