【发布时间】:2021-01-16 17:08:26
【问题描述】:
我有以下函数用于动态生成 SQL 查询,以使用 psycopg2 在 postgres 中插入 pandas 数据帧。我将使用此函数插入多个数据帧,这些数据帧可能没有数据库中的所有列,因此我不使用 pandas.to_sql()。
我不断收到错误 ValueError: unsupported format character: '(' 并且不知道是什么原因造成的。
任何帮助将不胜感激。
def execute_values(conn, df, schema, table):
"""
Using psycopg2.extras.execute_values() to insert the dataframe
"""
# Create a tuple of dicts from the dataframe values
dicts = tuple(df.to_dict('records'))
columns = sql.SQL(',').join(map(sql.Identifier, list(df.columns)))
values = sql.SQL(',').join(map(sql.Placeholder, list(df.columns)))
# SQL query to execute
query = sql.SQL('INSERT INTO {} ({}) VALUES ({})').format(
sql.Identifier(schema, table),
columns,
values
)
cursor = conn.cursor()
try:
extras.execute_values(cursor, query, dicts)
conn.commit()
except (Exception, psycopg2.DatabaseError) as error:
print("Error: %s" % error)
conn.rollback()
cursor.close()
raise
print("execute_values() done")
cursor.close()
【问题讨论】:
-
如果我关注这个
INSERT INTO {} ({}) ..应该是INSERT INTO {}.{} ({})...。并且sql.Identifier()需要拆分为一个用于架构和一个用于表。 -
@AdrianKlaver 根据 psycopg 文档 (psycopg.org/docs/sql.html):可以将多个字符串传递给对象以表示限定名称,即以点分隔的标识符序列。示例:
query = sql.SQL("select {} from {}").format( sql.Identifier("table", "field"), sql.Identifier("schema", "table")) print(query.as_string(conn)) select "table"."field" from "schema"."table" -
你使用的是什么版本的
psycopg2? -
@AdrianKlaver psycopg2 v2.8.6
-
嗯,这已经够新了。那么接下来的嫌疑人是
columns和values。在两者上尝试print()以查看实际存在的内容。看看schema和table传递的内容也不会有什么坏处。
标签: postgresql psycopg2