Python / psycopg2 оператор WHERE IN


81

Який правильний метод, щоб список (countryList) був доступний через% s у операторі SQL?

# using psycopg2
countryList=['UK','France']

sql='SELECT * from countries WHERE country IN (%s)'
data=[countryList]
cur.execute(sql,data)

Як і зараз, він помиляється після спроби запустити "WHERE country in (ARRAY [...])". Чи є спосіб зробити це інакше, як за допомогою маніпулювання рядками?

Дякую

Відповіді:


133

Для INоператора вам потрібна кортеж замість списку та видалення дужок із рядка SQL.

# using psycopg2
data=('UK','France')

sql='SELECT * from countries WHERE country IN %s'
cur.execute(sql,(data,))

Під час налагодження ви можете перевірити, чи правильно побудований SQL

cur.mogrify(sql, (data,))

Дякуємо за швидку відповідь!
Метт

1
Якщо у вас виникли проблеми навіть після прочитання цієї відповіді, перечитайте її ще раз дуже повільно. Це кортеж кортежів, і ви повинні видалити парани навколо% s, якщо вони там є. Це мене спокусило, бо в моєму простішому тесті використовувалося лише одне значення, і все працювало. Просто виконуйте це саме так, як Брайан це виписав.
zachaysan

40

Щоб трохи пояснити відповідь та звернутися до іменованих параметрів та перетворити списки в кортежі:

countryList = ['UK', 'France']

sql = 'SELECT * from countries WHERE country IN %(countryList)s'

cur.execute(sql, { # You can pass a dict for named parameters rather than a tuple. Makes debugging hella easier.
    'countryList': tuple(countryList), # Converts the list to a tuple.
})

1
Дякуємо за підказку щодо передачі дикту. Це набагато краще.
Джек

Чи можна це реалізувати з кількома реченнями WHERE x IN та кількома списками у словнику?
Одіссео,

1
Виправлення: @Odisseo Так, із всемогутнім АБО. Напр .:cur.execute("SELECT * FROM table WHERE col IN %(list1)s OR col IN %(list2)s", {'list1': tuple(1,2,3), 'list2' = tuple(4,5,6)})
Джошуа Бернс

12

Ви можете використовувати список python безпосередньо, як показано нижче. Він діє як оператор IN у SQL, а також обробляє порожній список без помилок.

data=['UK','France']
sql='SELECT * from countries WHERE country = ANY (%s)'
cur.execute(sql,(data,))

джерело: http://initd.org/psycopg/docs/usage.html#lists-adaptation


Можна також використовувати прийняту відповідь, але з cur.execute(sql, (tuple(data),))
Адам Хьюз
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.