Pandas sqlite read_sql динамический в предложении

Я пытаюсь использовать функцию pandas read_sql для запроса некоторых данных из базы данных sqlite. Мне нужно использовать параметризованный SQL, который содержится в предложении (List) и некоторых статических параметрах.

Ниже мой запрос

battingDataQuery = ('SELECT ID, MATCH_DATE, ROLE, DOWN_NUM, NAME, RUNS,' 
                    'MATCH_ID, TEAM_NAME, VERSUS_TEAM_NAME, GROUND_NAME ' 
               'FROM BATTING_DATA WHERE ID in ({1}) '
                'AND DOWN_NUM < {0} AND MATCH_TYPE = {0}')

Я правильно добавил заполнители, используя формат

battingDataQuery = battingDataQuery.format('?', ','.join('?' * len(playerIdList)))

Мой сгенерированный SQL выглядит следующим образом

'SELECT ID FROM BATTING_DATA WHERE ID in (?,?,?,?,?) AND DOWN_NUM < ? AND MATCH_TYPE = ?'

Я застрял в последней части, где я отправляю параметры следующим образом:

battingDataDF = pd.read_sql_query(battingDataQuery , conn, params=(playerIdList,battingDownNum,'\'T20\''))

Я получаю следующую ошибку при использовании этого

Поставлено неправильное количество креплений. Текущий оператор использует 7, и есть 3 поставленных.

Я пытался использовать следующие варианты, но все равно получаю ту же ошибку

battingDataDF = pd.read_sql_query(battingDataQuery , conn, params=[playerIdList,battingDownNum,'\'T20\'']) # same error

battingDataDF = pd.read_sql_query(battingDataQuery , conn, params=[playerIdList,battingDownNum,'\'T20\'']) # same error

battingDataDF = pd.read_sql_query(battingDataQuery , conn, params=[tuple(playerIdList),battingDownNum,'\'T20\'']) # same error
1
0
371
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы должны предоставить список из 7 параметров для ваших 7 вопросительных знаков:

battingDataDF = pd.read_sql_query(battingDataQuery , conn, params=playerIdList + [battingDownNum, "'T20'"])

(вы указали 3 параметра: список из 5 чисел, число и строку, отсюда и ошибка)

@Neel: извините за несколько правок/удалений, теперь все правильно и проверено.

Stef 21.12.2020 15:02

спасибо, это сработало. Хотя я смог найти другой вариант, который работал

Neel 25.12.2020 17:55

Ответ, учитывая, что мой @stef сработал, но я смог найти другой вариант, который сработал. Так хотел опубликовать это ради завершения

battingDataDF = pd.read_sql_query(battingDataQuery , conn, params=(*playerIdList,battingDownNum,matchType))

*вызывает распаковку списка, что приводит к предоставлению правильного количества аргументов

Не уверен, какой подход лучше. Если кто-то может пролить свет на это, это будет здорово.

Я думаю, это просто вопрос вкуса: playerIdList + [battingDownNum, "'T20'"] преобразует два последних аргумента в список, а затем объединяет два списка, тогда как (*playerIdList, battingDownNum, "'T20'") сначала распаковывает список, а затем преобразует все аргументы обратно в кортеж. Таким образом, в обоих случаях мы получаем список или кортеж всех аргументов, которые в конечном итоге превращаются в список и объединяются с оператором запроса.

Stef 25.12.2020 23:07

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

Stef 25.12.2020 23:08

Другие вопросы по теме