问题
I am trying to run a query of the form:
SELECT {} from TABLE where foo = VALUE
But I want to be able to provide a list to replace the {}
According to the psycopg docs, in order to do this safely, you need to use the sql.Identifier
function, in order to properly escape the parameter, and then do something like this:
SQL = sql.SQL(
"SELECT {} FROM foo WHERE bar = %s"
).format(identifier)
cursor.execute(SQL, [VALUE])
This works, when identifier
is a single element, but I need it to be an arbitrary number. For example if:
identifier = ["abc", "def"]
and
VALUE = 4
SQL = SELECT abc def FROM foo WHERE bar = 4
I've tried running sql.Identifier(x)
for every member of identifier
, but that gave "abc""def"
, which is clearly not correct.
回答1:
You need to use sql.join(), to make it work like a list comprehension:
from psycopg2 import sql
cols = ["abc", "def"]
query = sql.SQL(
"select {0} from {1} where abc = %s").format(
sql.SQL(', ').join([sql.Identifier(c) for c in cols]),
sql.Identifier('foo')
)
cur = conn.cursor()
print(query)
print(cur.mogrify(query, ('1', )))
cur.execute(query, ('1', ))
print (cur.rowcount, cur.fetchall())
Output:
Composed([SQL('select '), Composed([Identifier('abc'), SQL(', '), Identifier('def')]), SQL(' from '), Identifier('foo'), SQL(' where abc = %s')])
select "abc", "def" from "foo" where abc = '1'
(1, [('1', '2')])
来源:https://stackoverflow.com/questions/58172051/sql-identifier-substitution-using-a-list-of-column-names