psycopg2 TypeError: не все аргументы, преобразованные во время форматирования строки

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

Вот запрос (я использую объект Trac db для подключения к базе данных):

cursor.execute("""SELECT name FROM "%s".customer WHERE firm_id='%s'""" % (schema, each['id']))

схема и каждый ['id'] - это простые строки

print("""SELECT name FROM "%s".customer WHERE firm_id='%s'""" % (schema, each['id']))

Результат: SELECT name FROM "Planing".customer WHERE firm_id='135'

Ошибка error is remove quote after firm_id=, но в этом случае параметр обрабатывается целым числом, а ::text приводит к той же ошибке.

Ответ 1

Вы не должны использовать строковую интерполяцию для передачи переменных в запросах к базе данных, но использование строковой интерполяции для установки имени таблицы хорошо (если это не внешний ввод или вы ограничиваете допустимое значение). Попробуйте:

cursor.execute("""SELECT name FROM %s.customer WHERE firm_id=%%s""" % schema, each['id'])

Правила использования API БД предоставляет руководство по программированию для базы данных.

Ответ 2

В моем случае я не осознавал, что вам нужно передать кортеж для cursor.execute. У меня было это:

cursor.execute(query, (id))

Но вместо этого мне нужно было передать кортеж

cursor.execute(query, (id,))

Ответ 3

У меня такая же ошибка, и я не мог понять, как это исправить, в конце концов, это была моя глупая ошибка, потому что у меня не было достаточно параметров, соответствующих количеству элементов в кортеже:

con.execute("INSERT INTO table VALUES (%s,%s,%s,%s,%s)",(1,2,3,4,5,6))

Обратите внимание, что у меня есть 5 элементов в значениях, которые нужно вставить в таблицу, но 6 в кортеже.

Ответ 4

Правильный способ передачи переменных в команде SQL использует второй аргумент метода execute(). И я думаю, вы должны удалить одинарные кавычки из второго параметра, прочитать об этом здесь - http://initd.org/psycopg/docs/usage.html#the-problem-with-the-query-parameters.

Обратите внимание, что вы не можете передать имя таблицы в качестве параметра для execute и это считается плохой практикой, но есть некоторые обходные пути:
Передача имени таблицы в качестве параметра в psycopg2
psycopg2 cursor.execute() с параметром SQL query вызывает синтаксическую ошибку

Чтобы передать имя таблицы, попробуйте следующее:

cursor.execute("""SELECT name FROM "%s".customer WHERE firm_id=%s""" % (schema, '%s'), (each['id'],))

Ответ 5

Использовать AsIs

from psycopg2.extensions import AsIs

cursor.execute("""
    select name 
    from %s.customer 
    where firm_id = %s
    """, 
    (AsIs(schema), each['id'])
)