Используйте список в подготовленном утверждении - PullRequest
1 голос
/ 27 марта 2020

Я хочу использовать Python list (или set на самом деле) в моем execute, но я не совсем понимаю.

BRANDS = {
  'toyota',
  'ford',
  'dodge',
  'spyker'
}

cur = connection.cursor()
cur.execute("SELECT model FROM cars WHERE brand IN (%s)", (list(BRANDS),)

Как я могу использовать set или list в предложении IN в psycopg2?

1 Ответ

1 голос
/ 27 марта 2020

psycopg2 преобразует списки в массивы , а (%s) означает одно значение внутри кортежа, так что это, очевидно, неверно.

То, что вы хотите сделать, это либо:

  • let postgres преобразование кортежа в кортеж
    cur.execute("SELECT model FROM cars WHERE brand IN %s", (tuple(BRANDS),))
    
  • использование операторов массива с массивом
    cur.execute("SELECT model FROM cars WHERE brand = any(%s)", (list(BRANDS),))
    

Производительность должна быть эквивалентной, I обычно рекомендуют =any(), потому что типизация имеет больше смысла , и она работает, даже если параметр пуст , postgres делает не как пустые кортежи, поэтому brand in () генерирует ошибку. brand = any('{}') однако работает отлично.

О, и * psycogp2 execute полностью доволен списком параметров, я считаю, что он гораздо более читабелен и менее подвержен ошибкам, поэтому я рекомендую его :

cur.execute(
    "SELECT model FROM cars WHERE brand = any(%s)", [
    list(BRANDS)
])
...