SQL identifier substitution - Using a list of column names

余生长醉 提交于 2021-01-28 07:40:40

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!