Как запрос Python psycopg2 в состоянии с массивом uuid

#python #postgresql #psycopg2

Вопрос:

Для данной таблицы

 create table test_db (
  id uuid
)
 

В Python с библиотекой psycopg2 мы можем выполнить запрос

 cursor.execute("select * from test_db where id in"  
   " ('5ed11bbf-ffd1-4124-ba3d-5e392dc9db96','14acfb5b-3b09-4728-b3b3-8cd484b310db')")
 

Но если я параметрирую id , измените на

 cursor.execute("select * from testdb where id in (%s)",
   ("'5ed11bbf-ffd1-4124-ba3d-5e392dc9db96','14acfb5b-3b09-4728-b3b3-8cd484b310db'",))
 

Это не работает, говорит

psycopg2.ошибки.Недопустимое представление текста: недопустимый синтаксис ввода для типа uuid: «‘5ed11bbf-ffd1-4124-ba3d-5e392dc9db96’,’14acfb5b-3b09-4728-b3b3-8cd484b310db'»

Как я могу использовать in (%s) массив uuid?

Ответ №1:

Один %s на значение.

 cursor.execute(
   "select * from testdb where id in (%s, %s)",
   ('5ed11bbf-ffd1-4124-ba3d-5e392dc9db96','14acfb5b-3b09-4728-b3b3-8cd484b310db')
)
 

Комментарии:

1. Входные идентификаторы представляют собой список. Или сделайте так cursor.execute(f'select * from testdb where id in ({','.join(['%s'] * len(ids)}), ids)

Ответ №2:

У вас есть дополнительные кавычки, поэтому вы передаете только один аргумент, который является строкой.

Вы можете использовать кортеж и использовать IN , но использование списка и any() является лучшим вариантом, потому что он не взорвется вам в лицо, как только вы передадите пустой список.

 cursor.execute("select * from testdb where id = any(%s)",
   ([UUID('5ed11bbf-ffd1-4124-ba3d-5e392dc9db96'), UUID('14acfb5b-3b09-4728-b3b3-8cd484b310db')],))
 

Это может работать без использования UUID, но вы просто путаете систему типов таким образом.

Комментарии:

1. курсор.выполнить(«выберите * из базы данных тестов, где идентификатор = любой(%s)», ([‘5ed11bbf-ffd1-4124-ba3d-5e392dc9db96′, ’14acfb5b-3b09-4728-b3b3-8cd484b310db’],)) E psycopg2.ошибки. Неопределенная функция: оператор не существует: uuid = текст E СТРОКА 1: выберите * из базы данных тестов, где id = любой(МАССИВ[‘5ed11bbf… E ^ E ПОДСКАЗКА: Ни один оператор не соответствует заданному имени и типам аргументов. Возможно, вам потребуется добавить явные приведения типов.

2. Как написано на tin, вы можете добавить явное приведение, например, использовать %s::uuid[] в качестве заполнителя.

Ответ №3:

Спасибо за ответ @piro, после нескольких попыток получил рабочий код

 cursor.execute("select * from testdb where id = any(%s::uuid)",
   (['5ed11bbf-ffd1-4124-ba3d-5e392dc9db96',
     '14acfb5b-3b09-4728-b3b3-8cd484b310db'],))
 

и id = any(%s::uuid) не может быть заменен на id in (%s::uuid) .