Ошибка «слишком мало параметров» со списком значений для условия IN - PullRequest
0 голосов
/ 26 июня 2018

Я запрашиваю базу данных MS Access из Python, используя модуль pyodbc. Я могу сделать это, если я запрашиваю все записи в таблице, но когда я добавляю предложение where, я получаю сообщение об ошибке.

Это мой код:

wpc_ids = ['WPCMOOTEST2', 'WPCMOOTEST1']
conn = pyodbc.connect(r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=P:\Conservation Programs\Natural Heritage Program\Data Management\ACCESS databases\POND_entry\POND_be.accdb;')
cursor = conn.cursor()
wpc_list = ','.join(str(x) for x in wpc_ids)
cursor.execute('SELECT * FROM pools WHERE wpc_id IN (%s)'%wpc_list)

Я получаю следующую ошибку:

Error: ('07002', u'[07002] [Microsoft][ODBC Microsoft Access Driver] Too few parameters. Expected 2. (-3010) (SQLExecDirectW)')

Я не получаю эту ошибку без предложения where, поэтому я не уверен, какой второй параметр мне нужен. Кто-нибудь может помочь с этим?

1 Ответ

0 голосов
/ 26 июня 2018
cursor.execute(
    'SELECT * FROM pools WHERE wpc_id IN ({})'.format(
        ','.join('?'*len(wpc_ids))), wpc_ids
)

Пояснение:

Существует PEP о базах данных, PEP249, вы можете прочитать его здесь https://www.python.org/dev/peps/pep-0249/

Этот PEP определяет, каким должен быть API модулей базы данных. pyodbc - это модуль базы данных, который вы используете, и он совместим с PEP249.

Одна из вещей, определяемых PEP, заключается в том, что каждый модуль должен иметь paramstyle. pyodbc.paramstyle - это qmark, поэтому вы используете '?' с pyodbc. Подробнее https://www.python.org/dev/peps/pep-0249/#paramstyle

Теперь вместо создания запроса в виде строки и отправки его в базу данных идея состоит в том, чтобы использовать передачу параметров, которая является способом отправки запроса и параметров по отдельности ... Он использует paramstyle для поместите заполнители в запрос, а затем передайте последовательность параметров в качестве второго параметра execute. Пример:

sql = 'SELECT * FROM foo WHERE id = ? AND text_col = ?'
params = (12, 'testing')
cursor.execute(sql, params)

Обратите внимание, что это не смешивание параметров со строкой. Код передает их как два отдельных аргумента в .execute(). Это означает, что задачей базы данных будет безопасная интерполяция.

Поскольку вы хотите передать несколько значений в запрос, вы должны сгенерировать строку, содержащую количество заполнителей, разделенных запятой, то же число, что и элементов в списке:

','.join('?'*len(wpc_ids)))  
 # will generate ?,?,?,?,? according with length of list
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...