Postgres: Python: TypeError: SQL.__init__() takes 2 positional arguments but 3 were given

Postgres: Python: TypeError: SQL.__init__() takes 2 positional arguments but 3 were given

您好,我的代码出错了,有人可以帮我吗?

def query_builder(self, field_name, table_name, pkey, id):

    queryx=sql.SQL("select {field} from {table} where {pkey} = %s",(id)).format(
        field=sql.Identifier(field_name),
        table=sql.Identifier(table_name),
        pkey=sql.Identifier(pkey))
    
    self.cur.execute(queryx.as_string(self.conn))

我假设您正在使用 psycopg2

如果是这样,首先是:

"select {field} from {table} where {pkey} = %s",(id) ..."

不要在字符串中包含参数 (id)。这也不是元组中单个值的正确形式。 Python 要求它是 (id,),注意逗号。

第二个:

self.cur.execute(queryx.as_string(self.conn))

应该是:

self.cur.execute(queryx, (id,))

execute 是您提供参数的地方。此外,可组合项 sql.SQL(...) 可以直接传递给 execute,而无需通过 as_string 运行。有关更多示例,请参阅此处 sql

更新

使用“*”有两种方式:

cur.execute(sql.SQL("select * from {table} where {pkey} = %s).format(table.sql.Identifier(table_name), pkey=sql.Identifier(pkey))

--OR

cur.execute(sql.SQL("select {field} from {table} where {pkey} = %s).format(field=sql.SQL("*"), table=sql.Identifier(table_name), pkey=sql.Identifier(pkey))

警告,第二个确实允许 SQL 注入,因为 sql.SQL() 不会转义值。

关于多个字段,文档的 sql 部分有多个示例。例如:

If part of your query is a variable sequence of arguments, such as a comma-separated list of field names, you can use the SQL.join() method to pass them to the query:

query = sql.SQL("select {fields} from {table}").format(
    fields=sql.SQL(',').join([
        sql.Identifier('field1'),
        sql.Identifier('field2'),
        sql.Identifier('field3'),
    ]),
    table=sql.Identifier('some_table'))