В приведенном ниже примере сценарий 1 работает нормально как в коде (Code 1, так и в коде 2). Но сценарий 2 не работает в коде 1.
Мое требование Tuple должно продолжать повторяться, пока оно не заполнит всю строку форматирования в запросе динамически. Потому что, где предложения не являются постоянными для всех запросов.
Сценарий 1 #
query = SELECT * FROM test.order where total_price in {}
Кортеж:
finTup=((125, 125, 125, 125),)
SELECT * FROM test.order where total_price in (125, 125, 125, 125)
Сценарий 2 #
query = SELECT * FROM test.order WHERE order_id IN {} AND product_id IN {}
Кортеж:
finTup=((101, 105, 106, 107), (2, 2, 2, 2))
Код 1:
frt = 'finTup[{}]'
half = ''
val = ''
i = 0
le = len(finTup)
for i in range(le):
print(i)
print(eval(frt.format(i)))
if i == le -1:
half = half + frt.format(i)
val = val + " " + frt.format(i)
else:
half = half + frt.format(i)+', '
val = val + " " + frt.format(i)+', '
temp2 = query.format(eval(val))
Код 2:
if le == 1:
query = query.format(finTup[0])
elif le == 2:
query = query.format(finTup[0], finTup[1])
elif le == 3:
query = query.format(finTup[0], finTup[1], finTup[2])
elif le == 4:
query = query.format(finTup[0], finTup[1], finTup[2], finTup[3])
Error:
temp2 = query.format(eval(val))
IndexError: tuple index out of range
Пожалуйста, помогите мне исправить это.
Здравствуйте, у вас есть эта ошибка, потому что вы пытаетесь предоставить один аргумент функции format
которая ожидает два параметра (так как у вас есть 2 {}
).
Примечание. Избегайте использования функции eval
... Это довольно не рекомендуется, даже в той ситуации, в которой вы сейчас находитесь. Все можно сделать без оценки str
.
В дальнейшем я запускаю код для сценария № 2, т.е.
query2 = """SELECT * FROM test.order WHERE order_id IN {} AND product_id IN {}"""
finTup = ((101, 105, 106, 107), (2, 2, 2, 2))
Представим, что вы обновляете свой код для отладки следующим образом:
frt = 'finTup[{}]'
half = ''
val = ''
i = 0 # btw, you don't need to initialize i here
le = len(finTup)
for i in range(le):
if i == le -1:
half = half + frt.format(i)
val = val + " " + frt.format(i)
else:
half = half + frt.format(i)+', '
val = val + " " + frt.format(i)+', '
print val
print eval(val)
temp2 = query.format(eval(val))
Ваш результат должен быть:
vars[0], vars[1]
((101, 105, 106, 107), (2, 2, 2, 2))
Итак, представьте, что вы пишете код python из вышеприведенного вывода, что бы вы сделали:
query.format(((101, 105, 106, 107), (2, 2, 2, 2)))
Фактически вы предоставляете один параметр tuple
типа с двумя элементами. Но важно то, что вы предоставляете format
с одним параметром. Функция format
попытается получить доступ ко второму параметру, который вы не предоставляете. Это ломает.
Посмотрите на эту статью SO. Он показывает вам, как использовать оператор *
. Он в основном преобразует list
или tuple
в последовательность элементов. Идеально подходит для параметров функций и т.д.
Итак, применительно к вашему текущему делу:
temp2 = query.format(*eval(val))
И трюк сделан.
Теперь позвольте испортить код 1 и используйте то, что мы узнали, с кодом 2. Нам нужно распаковать tuple
tuple
в параметры для подачи в format
. Итак, почему бы просто не сделать:
# I renamed 'finTup' to 'vars' since I don't know what it means
def get_query(query, vars):
return query.format(*vars)
Он в основном объединяет логику кода 1 и кода 2 в одну строку.