локальная переменная 'sql' указана перед присваиванием - PullRequest
0 голосов
/ 19 марта 2019

Привет, я пытаюсь написать функцию, используя 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': имеют собственную функцию для выполнения, я хочу, чтобы другие условия перешли к последней функции курсора в конце кода.

Ответы [ 5 ]

1 голос
/ 19 марта 2019

Как только вы запустите программу, я полагаю, что это произойдет (Read #)

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)

Маби перед первым оператором if и пустой переменной sql. (или любое другое значение по умолчанию)

0 голосов
/ 19 марта 2019

После того, как я изменил

 elif params["type"] == 'product':
      get_product_report(request)

до

 elif params["type"] == 'product': 
      return get_product_report(params)

это сработало, потому что get_product_report - это собственная функция, поэтому не было никакого результата возврата в условие param = 'product', поэтому оно неверно из строки параметров продукта (return None)

0 голосов
/ 19 марта 2019

вы можете задать sql значение по умолчанию в начале:

def api_report(request):
    params = request.GET
    sql=''
0 голосов
/ 19 марта 2019

Вам следует изменить последовательность if, чтобы игнорировать случаи, когда sql пусто. В противном случае вы можете просто добавить sql = 'some default value' поверх него, но это уже трудно прочитать.

0 голосов
/ 19 марта 2019

Issue

local variable 'sql' referenced before assignment означает, что sql еще не назначен, когда вы пытаетесь использовать его с cursor.execute(sql).

Itэто тот случай, когда params["type"] == 'product' или когда ни одна из ваших проверок if / elif не верна.Например, if params["type"] - это foo, sql не будет назначено.

Решение

Присвойте значение sql, когда params["type"] == 'product'

Используйте оператор else, чтобы либо присвоить значение sql, либо выдать ошибку, если params["type"] не является ожидаемой строкой.

...