Подстановка идентификатора SQL - Использование списка имен столбцов - PullRequest
1 голос
/ 30 сентября 2019

Я пытаюсь выполнить запрос в форме:

SELECT {} from TABLE where foo = VALUE

Но я хочу иметь возможность предоставить список для замены {}

Согласно документам psycopg, чтобы сделать это безопасно, вам нужно использовать функцию sql.Identifier, чтобы правильно экранировать параметр, а затем сделать что-то вроде этого:

SQL = sql.SQL(
    "SELECT {} FROM foo WHERE bar = %s"
).format(identifier)

cursor.execute(SQL, [VALUE])

Это работает,когда identifier является единственным элементом, но мне нужно, чтобы это было произвольное число. Например, если:

identifier = ["abc", "def"]

и

VALUE = 4

SQL = SELECT abc def FROM foo WHERE bar = 4

Я пытался запустить sql.Identifier(x) для каждого члена identifier, но это дало "abc""def", что явно не правильно.

1 Ответ

1 голос
/ 30 сентября 2019

Вам нужно использовать sql.join () , чтобы заставить его работать как понимание списка:

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())

Вывод:

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')])
...