首页 > 解决方案 > psycopg2 - 使用 extras.batch_execution 插入变量库

问题描述

我正在使用 psycopg2 将 pandas 数据框插入到 postgres 中。下面的代码:

...
import psycopg2.extras as extras

tuples = [tuple(x) for x in df.to_numpy()]
cols = ','.join(list(column_list))
query  = "INSERT INTO %s(%s) VALUES (%%s,%%s,%%s,%%s,%%s)" % (table  , cols)

extras.execute_batch(cursor, query, tuples, page_size = 100)
...

这行得通!

在这里,我将 df 转换为元组,并且我认为%%s在运行时在执行 extras.execute_batch 时采用此值。

问题是,为此,我需要硬编码%%s列的次数。

在此示例中,它有 5 列,因此我使用的是%%s,%%s,%%s,%%s,%%s.

有没有办法让它可变?

这是我尝试过的:

...
tuples = [tuple(x) for x in df.to_numpy()]
cols = ','.join(list(column_list))

vals_frame = len(column_list) * """%%s,"""
vals_frame = vals_frame[:-1]
print('vals_frame: ',vals_frame)
query  = query  = "INSERT INTO %s(%s) VALUES("+vals_frame+")" % (table  , cols)

extras.execute_batch(cursor, query, tuples, page_size = 100)
...

这打印:

vals_frame: '%%s,%%s,%%s,%%s,%%s'

这是我想要的,但是在创建查询时出现以下错误:

TypeError:字符串格式化期间并非所有参数都转换了

如何度过这个难关?

我努力了:

vals_frame = len(column_list) * """\%\%s,"""
vals_frame = len(column_list) * """\\%%s,"""

但这似乎不起作用。有人可以帮忙吗?

标签: pythonpandas

解决方案


问题是 % 的位置。由于运算符优先级,% 绑定比 + 更紧密。所以:

query  = "INSERT INTO %s(%s) VALUES("+vals_frame+")" % (table  , cols)

这里的%运算符适用于字符串“)”。以下是一些可供考虑的替代方案:

query  = "INSERT INTO %s(%s) VALUES(" % (table, cols) +vals_frame+")"
query  = ("INSERT INTO %s(%s) VALUES("+vals_frame+")") % (table  , cols)
query  = "INSERT INTO %s(%s) VALUES(%s)" % (table, cols, vals_frame)

或者,通过使用 f 字符串来避免该问题:

query  = f"INSERT INTO {table}({cols}) VALUES({vals_frame});"

推荐阅读