#python #sql #django #indentation
#python #sql #django #отступ
Вопрос:
Привет, я пытаюсь написать функцию, используя if / elif, у меня возникли проблемы при попытке выполнить последнюю функцию курсора после elif. Я думаю, что мой отступ неверен, и я пытался найти, где ошибка, уже более суток :
def api_report(request):
params = request.GET
if params["type"] == 'revenue':
sql = get_revenue_query(params)
elif params["type"] == 'order_count':
sql = get_order_created_count(params)
elif params["type"] == 'product_count':
sql = get_product_count(params)
elif params["type"] == 'order_card_created_count':
sql = get_order_card_created_count(params)
elif params["type"] == 'product_count':
sql = get_product_count(params)
elif params["type"] == 'card':
sql = get_card_query(params)
elif params["type"] == 'order_not_card_created_count':
sql = get_order_not_card_created_count(params)
elif params["type"] == 'product':
get_product_report(params)
elif params["type"] == 'order_rate_by_district':
sql = get_order_rate_by_district(params)
with connection.cursor() as cursor:
cursor.execute(sql)
rows = cursor.fetchall()
data = []
for row in rows:
data.append(OrderRateDataEntry(row[0], row[1], row[2]))
serializer = OrderRateDataEntrySerializer(data, many=True)
return JsonResponse(serializer.data, safe=False)
with connection.cursor() as cursor:
cursor.execute(sql)
rows = cursor.fetchall()
data = []
for row in rows:
data.append(TimeSeriesDataEntry(row[0], row[1]))
serializer = TimeSeriesDataEntrySerializer(data, many=True)
return JsonResponse(serializer.data, safe=False)
Ошибка:
cursor.execute(sql) UnboundLocalError:
local variable 'sql' referenced before assignment
У elif params["type"] == 'product':
и elif params["type"] == 'order_rate_by_district':
есть своя функция для выполнения, я хочу, чтобы другие условия переходили к последней функции курсора в конце кода.
Комментарии:
1. первый elif должен быть if? если ваш код не работает ни с одним из elifs, вы никогда не определяете sql, и в шестой последней строке вашего кода вы вызываете sql
2. должен ли я добавить «pass» к последнему elif? значит, другие условия могут использовать sql?
3. если
params["type"] == 'product'
вы получите сообщение об ошибке, потому чтоsql
не определено. Это желаемое поведение? Что вы хотите, чтобы ваша функция делала в этом случае? она не может выполнять никакихsql
действий с курсором, вы хотите, чтобы функция завершила работу и вернула что-то?4. Вы можете добавить
else
инструкцию в конце. Все еще возможно, что при использовании только последовательностиif
иelif
ssql
значение в конечном итоге будет неопределенным.
Ответ №1:
Как только вы запустите программу, это то, что, как я предполагаю, произойдет (Читать #)
def api_report(request):
params = request.GET
if params["type"] == 'revenue': # False so sql is not made, move to next elif
sql = get_revenue_query(params)
elif params["type"] == 'order_count': # False so sql is not made, move to next elif
sql = get_order_created_count(params)
elif params["type"] == 'product_count': # False so sql is not made, move to next elif
sql = get_product_count(params)
elif params["type"] == 'order_card_created_count': # False so sql is not made, move to next elif
sql = get_order_card_created_count(params)
elif params["type"] == 'product_count': # False so sql is not made, move to next elif
sql = get_product_count(params)
elif params["type"] == 'card': # False so sql is not made, move to next elif
sql = get_card_query(params)
elif params["type"] == 'order_not_card_created_count': # False so sql is not made, move to next elif
sql = get_order_not_card_created_count(params)
elif params["type"] == 'product': # False so sql is not made, move to next elif
get_product_report(request) # P.S There is also a chance that if this is run then sql variable will also not be made!
elif params["type"] == 'order_rate_by_district': # This is also false so code leaves.
sql = get_order_rate_by_district(params)
with connection.cursor() as cursor:
cursor.execute(sql)
rows = cursor.fetchall()
data = []
for row in rows:
data.append(OrderRateDataEntry(row[0], row[1], row[2]))
serializer = OrderRateDataEntrySerializer(data, many=True)
return JsonResponse(serializer.data, safe=False)
pass
# When the code is here it still didn't made variable sql. Thus so will crashes when refere to variable sql as it wasn't yet created
with connection.cursor() as cursor:
cursor.execute(sql) # sql was never made here and thus doesn't exist. Code crashes here.
rows = cursor.fetchall()
data = []
for row in rows:
data.append(TimeSeriesDataEntry(row[0], row[1]))
serializer = TimeSeriesDataEntrySerializer(data, many=True)
return JsonResponse(serializer.data, safe=False)
Maby перед первым оператором if make и пустой переменной sql. (или любое другое значение по умолчанию, которое вы предпочитаете)
Комментарии:
1. это опция, но это api, поэтому я не хочу, чтобы он выводил какие-либо данные, если в них нет параметров
2. Я думаю, что вы хотите заменить все 2-е соединение.cursro() … на оператор else: «else: data=[]», который не вернет никаких данных, если все предыдущие утверждения ложны. Это то, что вы имеете в виду?
3. второй захват sql должен выполняться для других условий, кроме product и order_rate_by_district
4. Какое условие вы хотите выполнить? Это в переменной params?
5. да, все переменные params будут использовать назначенный sql для выполнения 2-го захвата sql, который является последними 6 строками кода (за исключением тех 2 условий, о которых я говорю)
Ответ №2:
Проблема
local variable 'sql' referenced before assignment
означает, что sql
она еще не была назначена, когда вы пытаетесь использовать ее с cursor.execute(sql)
.
Это тот случай, когда params["type"] == 'product'
или когда ни одна из ваших проверок if / elif не верна. Например, if params["type"]
is foo
, sql
не будет присвоен.
Решение
Присваивайте значение sql, когда params["type"] == 'product'
Используйте else
инструкцию, чтобы либо присвоить значение sql, либо выдать ошибку, когда params["type"]
нет ни одной из ожидаемых строк.
Комментарии:
1. дело в том, что я включаю параметры [«type»] == ‘product’ в def с другим условием, но не хочу ли я использовать sql для этих параметров
Ответ №3:
Вам следует изменить свою последовательность if, чтобы игнорировать случаи, когда sql
она пуста. В противном случае вы могли бы просто добавить sql = 'some default value'
поверх нее, но это уже трудно читать.
Ответ №4:
вы можете присвоить sql значение по умолчанию в начале:
def api_report(request):
params = request.GET
sql=''
Ответ №5:
После того, как я изменил
elif params["type"] == 'product':
get_product_report(request)
Для
elif params["type"] == 'product':
return get_product_report(params)
это сработало, потому что get_product_report является его собственной функцией, поэтому не было никакого результата возврата к условию param = ‘product’, поэтому оно неверно в строке параметров продукта (return None)
Комментарии:
1. Это все равно приведет к сбою, если
params["type"]
нет ни одного из вариантов. Также произойдет сбой, если не будет параметра GET «type». Итак, если ваш URL-адрес «/ api / report», то простой вызов «/api /report» вызовет исключение, а вызов «/ api / report?type=blabla» также вызовет исключение. Не очень хороший дизайн.