psycopg2动态插入查询问题,标识符附近的语法错误。

5
我正在编写一个程序,从另一个源中提取大量数据并将其记录在Postgres数据库中。我需要一个函数,该函数接收目标表和包含变量字段的字典作为输入,然后根据需要插入它。这似乎应该很简单,但我在生成插入查询时遇到了问题。我在网上找到的示例要么是不完整的、过时的,要么当我修改它们以适应我的数据时根本不起作用。
以下是我组织的一个简单版本以解决这个问题。我已经尝试了许多变化,所以它现在可能不够干净。感觉有些非常简单的东西我只是没有注意到。
def insert_record():

    table = "test"
    record = {"name": "Jack", "id": 1}
    fields = record.keys()
    values = ", ".join(str(n) for n in record.values())

    query = sql.SQL("INSERT INTO {} ({}) VALUES ({});".format(
                    sql.Identifier(table),
                    sql.SQL(",").join(map(sql.Identifier, fields)),
                    sql.SQL(",").join(sql.Placeholder() * len(fields))
                    ))
    cursor = connection.cursor()

    print(query.as_string(connection))
    try:
        cursor.execute(query, (values,))
        connection.commit()
    except (Exception, psycopg2.DatabaseError) as error:
        print(error)
    cursor.close()

这将返回错误:

syntax error at or near "'test'"
LINE 1: INSERT INTO Identifier('test') (Composed([Identifier('name')...

看起来由于某些原因它实际上没有格式化查询,因为as_string函数返回未经格式化的内容:

"INSERT INTO Identifier('test') (Composed([Identifier('name'), SQL(','), Identifier('id')])) VALUES (Composed([Placeholder(''), SQL(','), Placeholder('')]));"

你有没有任何建议来修复这个问题,或者更好的处理动态查询的方法?

编辑:这是我的导入语句。

import psycopg2
from psycopg2 import extras, Error, sql

import psycopg2 from psycopg2 import extras, Error, sql - CyberArchaeologist
1
请注意,您调用的“format”是普通字符串类型的“format”,而不是sql.SQL的“format”。我认为这不是您想要的。您是否有错位的括号? - jjanes
没错,就是这样。我知道这可能只是一些微不足道的容易被忽略的问题,而我只是太过于接近它而没有看到。感谢你成为我的第二双眼睛。 - CyberArchaeologist
我遇到了同样的问题 :) - dtc
1个回答

3

您正在从字符串对象调用函数.format(),您必须从sql.SQL()对象类中调用.format()函数。

query = sql.SQL("INSERT INTO {} ({}) VALUES ({});").format(
                sql.Identifier(table),
                sql.SQL(",").join(map(sql.Identifier, fields)),
                sql.SQL(",").join(sql.Placeholder() * len(fields))
                )

参考:https://www.psycopg.org/docs/sql.html?highlight=literal#module-usage


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接