在psycopg2中传递参数

时间:2015-06-05 21:56:22

标签: python postgresql 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;

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

任何人都可以告诉我这里发生了什么?非常感谢!!!

3 个答案:

答案 0 :(得分:3)

使用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将显示它没有引用列名并按原样传递它们。

答案 1 :(得分:0)

原因是您将数组的字符串表示形式[' id',' name']作为SQL查询参数传递,而不是作为列名称传递。因此得到的查询类似于

SELECT 'id, name' FROM 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;

答案 2 :(得分:0)

如今,您可以使用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