在 psycopg2 中传递参数

Passing parameter in psycopg2

我正在尝试使用 psycopg2 访问 PostgreSQL:

sql = """
SELECT
    %s
FROM
    table;
"""

cur = con.cursor()
input = (['id', 'name'], )
cur.execute(sql, input)

data = pd.DataFrame.from_records(cur.fetchall())

但是返回的结果是:

             0
0   [id, name]
1   [id, name]
2   [id, name]
3   [id, name]
4   [id, name]

如果我尝试访问单列,它看起来像:

     0
0   id
1   id
2   id
3   id
4   id

列名周围的引号似乎有问题(单引号不应存在):

In [49]: print cur.mogrify(sql, input)

SELECT
    'id'
FROM
    table;

但我正在关注文档:http://initd.org/psycopg/docs/usage.html#

谁能告诉我这是怎么回事?非常感谢!!!

使用 AsIs 扩展

import psycopg2
from psycopg2.extensions import AsIs

column_list = ['id','name']
columns = ', '.join(column_list)

cursor.execute("SELECT %s FROM table", (AsIs(columns),))

并且 mogrify 将显示它没有引用列名并将它们按原样传递。

原因是您将数组 ['id'、'name'] 的字符串表示作为 SQL 查询参数而不是列名传递。所以结果查询类似于

SELECT 'id, name' FROM table

看起来您的 table 有 5 行,所以返回的结果只是每行的这个文字。

列名不能是SQL查询参数,可以是你可以在执行查询前准备的普通字符串参数-

sql = """
SELECT
    %s
FROM
    table;
"""

input = 'id, name'
sql = sql % input
print(sql)

cur = con.cursor()
cur.execute(sql)

data = pd.DataFrame.from_records(cur.fetchall())

在这种情况下,结果查询是

SELECT
    id, name
FROM
    table;

如今,您可以使用 sql.Identifier 以干净安全的方式执行此操作:

from psycopg2 import sql

statement = """
SELECT
    {id}, {name}
FROM
    table;
"""

with con.cursor() as cur:
  cur.execute(sql.SQL(statement).format(
    id=sql.SQL.Identifier("id"),
    name=sql.SQL.Identifier("name")
  ))

  data = pd.DataFrame.from_records(cur.fetchall())

这里有更多关于查询组合的信息:https://www.psycopg.org/docs/sql.html