postgresql 如何在extras.execute_values()中使用模板参数?

xt0899hw  于 2023-08-04  发布在  PostgreSQL
关注(0)|答案(2)|浏览(168)

我在psycopg2中使用extras.execute_values()方法,结果并没有像我预期的那样抛出:

countyid_landid_tuple_list = [(1,1),(1,2),(2,3)]
sql = "update agri_land set county_id = %s"
extras.execute_values(cur, sql, countyid_landid_tuple_list ,"%s where id = %s")

字符串
错误消息如下:

psycopg2.errors.SyntaxError: error:  grammar mistakes around "," or nearby
LINE 1: ...e agri_land set country_id = 1 where id = 1,1 where i...


基本上,文档在解释模板参数的用法方面非常糟糕。为什么没有更多的例子?
环境:

  • Python 3.7.9(64位)
  • psycopg2 2.9.5
  • PostgreSQL 12
jutyujz0

jutyujz01#

文件确实涵盖了这个案例。出发地:
https://www.psycopg.org/docs/extras.html#fast-execution-helpers

execute_values(cur,
... """UPDATE test SET v1 = data.v1 FROM (VALUES %s) AS data (id, v1)
... WHERE test.id = data.id""",
... [(1, 20), (4, 50)])

字符串
于是:

countyid_landid_tuple_list = [(1,1),(1,2),(2,3)]
sql = "update agri_land set county_id = data.v1 from (values %s) as data(v1,id) where id = data.id"
extras.execute_values(cur, sql, countyid_landid_tuple_list)

9jyewag0

9jyewag02#

psycopg2 extras.execute_values函数通常用于大容量插入操作,而不用于大容量更新操作,因为它以一种不容易允许WHERE子句因行而异的方式构造查询。
您可以考虑循环遍历元组列表并执行各个update语句。

countyid_landid_tuple_list = [(1,1),(1,2),(2,3)]
for county_id, land_id in countyid_landid_tuple_list:
    sql = "UPDATE agri_land SET county_id = %s WHERE id = %s"
    cur.execute(sql, (county_id, land_id))

字符串
如果你有大量的更新要做,你可以利用psycopg2的能力一次批处理和提交多个更新:

countyid_landid_tuple_list = [(1,1),(1,2),(2,3)]
with psycopg2.connect(DSN) as conn:
    with conn.cursor() as cur:
        for county_id, land_id in countyid_landid_tuple_list:
            sql = "UPDATE agri_land SET county_id = %s WHERE id = %s"
            cur.execute(sql, (county_id, land_id))
        conn.commit()


这样,您仍然可以获得将更新批处理到单个事务中的性能优势。它不会像批量插入那样快,但应该比单独执行和提交每个更新更有效。

相关问题