我正在编写一个使用psycopg2库为PostgreSQL数据库动态创建插入/更新/选择查询的功能。
我一直在尝试根据psycopg2 documentation提供的建议编写安全注入函数-使用sql.Sql
方法正确地组成查询。所有参数(表名,要插入的列,值)都动态传递给函数:
def insert(table, columns: list, values: list):
query = sql.SQL('INSERT INTO {} ({}) VALUES ({});').format(
sql.Identifier(table),
sql.SQL(', ').join(map(sql.Identifier, columns)),
sql.SQL(', ').join(map(sql.Identifier, values))
)
cursor = foo_connection.cursor()
cursor.execute(query)
当我尝试测试该功能时:
insert('test_table', ['col1', 'col2', 'col3'], ['1', '2', '3'])
我收到以下错误:
psycopg2.errors.UndefinedColumn: column "1" does not exist
LINE 1: ...e" ("col1", "col2", "col3") VALUES ("1", "2", ...
我不会取消错误,因为从技术上讲它甚至都不是列,而是要插入的值。
我认为查询的构成不正确,但是print(query.as_string(foo_connection))
的结果表明它似乎是正确的:
INSERT INTO "test_table" ("col1", "col2", "col3") VALUES ("1", "2", "3");
官方文档没有涵盖这种情况。谷歌搜索也没有给我答案。
所以,问题是:
答案 0 :(得分:2)
如Laurenz所说,在psycopg2文档中,它写为:
标识符通常代表数据库对象的名称,例如表或字段。
我还看到了Literals对象:
表示要包含在查询中的SQL值。
在格式化查询时,也许可以尝试用文字替换标识符:
query = sql.SQL('INSERT INTO {} ({}) VALUES ({});').format(
sql.Identifier(table),
sql.SQL(', ').join(map(sql.Identifier, columns)),
sql.SQL(', ').join(map(sql.Literals, values))
)
答案 1 :(得分:0)
我认为这是您对查询的引用。也许尝试在外面使用双打:
def insert(table, columns: list, values: list):
query = sql.SQL("INSERT INTO {} ({}) VALUES ({});").format(
sql.Identifier(table),
sql.SQL(', ').join(map(sql.Identifier, columns)),
sql.SQL(', ').join(map(sql.Literlas, values))
)
cursor = foo_connection.cursor()
cursor.execute(query)
答案 2 :(得分:0)
问题是您将值常量的格式设置为sql.Identifier
。
这导致它们用双引号而不是单引号引起来,因此PostgreSQL认为它们是表列。因此出现错误消息。
最好的做法是对文字使用%s
占位符,并将它们作为第二个参数传递给execute()
。