当 inserting/updateing 进入 psql 数据库时正确使用 %s

Correct usage of %s when inserting/updateing into a psql database

我想将值 (a,b,c,d) 插入数据库,如果三元组 (a,b,c) 已经存在,我想用新值 d 更新该行。为了速度,我想批量插入。我正在使用以下查询:

    query = """INSERT INTO table
                 (a, b, c, d)
                 VALUES (%(a)s, %(b)s, %(c)s, %(d)s)
                 ON CONFLICT (a, b, c)
                 DO UPDATE SET d = %(d)s"""            
    psycopg2.extras.execute_values(cursor, query, ((
            test_dict[line]['a'],
            test_dict[line]['b'],
            test_dict[line]['c'],
            test_dict[line]['d'])
            for line in test_dict))

这里 cur 是数据库的游标,test_dict 是字典。 但是,我收到以下错误:

ValueError: unsupported format character: '('

所以如果我将查询更改为

query = """INSERT INTO table
                 (a, b, c, d)
                 VALUES %s""" 

我不再收到此错误,但我也不知道如何告诉代码在发生冲突时更新值 d。

How do I then alter the line DO UPDATE SET d = %(d)s?

告诉 PostgreSQL,而不是 python,要更新的值:

DO UPDATE SET d = EXCLUDED.d

EXCLUDED 是您引用插入冲突的行的方式。

您将命名占位符与位置参数混合在一起。您需要执行以下操作:

query = """INSERT INTO table
                 (a, b, c, d)
                 VALUES (%(a)s, %(b)s, %(c)s, %(d)s)
                 ON CONFLICT (a, b, c)
                 DO UPDATE SET d = %(d)s"""            
    psycopg2.extras.execute_values(cursor, query, test_dict)

这假设 test_dict 实际上是一个字典列表