Salut, j'essaie d'écrire une fonction en utilisant if / elif, j'ai des problèmes en essayant d'exécuter la fonction de curseur finale après elif. Je pense que mon retrait est erroné et j'essaie de trouver où se situe l'erreur depuis plus d'un jour maintenant:
cursor.execute(sql) UnboundLocalError: local variable 'sql' referenced before assignment
L'erreur:
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)
Les elif params ["type"] == 'product':
et elif params ["type"] == 'order_rate_by_district':
ont leur propre fonction à exécuter, je veulent que les autres conditions sautent à la dernière fonction de curseur à la fin du code.
5 Réponses :
< gagnantIndice
variable locale 'sql' référencé avant affectation code> signifie que
sql code> n'a pas encore été attribué lorsque vous essayez de l'utiliser avec
cursor.execute ( sql)
.
C'est le cas lorsque params ["type"] == 'product'
ou lorsqu'aucune de vos vérifications if / elif n'est vraie. Par exemple, si params ["type"]
vaut toto
, sql
ne sera pas attribué.
<½Solution
Attribuez une valeur à sql lorsque params ["type"] == 'product'
Utilisez une instruction else
pour attribuer une valeur à sql ou générer une erreur lorsque params ["type"]
ne correspond à aucune de vos chaînes attendues.
le truc est que i params ["type"] == 'product' include dans la def avec une autre condition mais je ne veux pas utiliser sql pour ces paramètres
Une fois que vous exécutez le programme, c'est ce que je suppose qui se produit (Lire #)
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 avant la première instruction if make et variable sql vide. (ou quelle que soit la valeur par défaut que vous préférez)
c'est une option mais c'est une api donc je ne veux pas qu'elle produise des données s'il n'y a pas de passage de paramètres
Je pense que vous voulez remplacer la totalité du 2nd connection.cursro () ... par une instruction else: "else: data = []" qui ne renverra aucune donnée si toutes les déclarations précédentes sont fausses. C'est ce que tu veux dire?
la deuxième saisie SQL est à exécuter pour d'autres conditions sauf product et order_rate_by_district
Quelle est la condition que vous souhaitez exécuter? Est-ce dans la variable params?
oui toutes les variables params utiliseront le sql assigné pour exécuter le 2nd sql grab qui est les 6 dernières lignes du code (sauf pour ces 2 conditions dont je parle)
qu'est-ce qui est censé se passer si param ["type"] n'est dans aucun des elif? Que doit-il se passer alors?
Vous devriez réorganiser votre séquence if pour ignorer les cas où sql
est vide. Sinon, vous pouvez simplement ajouter sql = 'some default value'
dessus, mais c'est déjà difficile à lire.
vous pouvez donner à sql une valeur par défaut au début:
def api_report(request): params = request.GET sql=''
Après avoir changé le
elif params["type"] == 'product': return get_product_report(params)
en
elif params["type"] == 'product': get_product_report(request)
cela a fonctionné car le get_product_report est sa propre fonction donc il n'y a pas eu de retour result to param = condition 'product' donc il est faux de la ligne de param product (return None)
Cela plantera toujours si params ["type"]
ne fait pas partie des choix. Il plantera également s'il n'y a pas de paramètre GET "type". Donc, si votre URL est "/ api / report", le simple fait d'appeler "/ api / report" déclenchera une exception et l'appel de "/ api / report? Type = blabla" déclenchera également une exception. Pas un bon design.
le premier elif devrait être si? si votre code ne rencontre aucun des elifs, vous ne définissez jamais sql et à la sixième dernière ligne de votre code, vous appelez sql
dois-je ajouter "passer" au dernier elif? donc les autres conditions peuvent utiliser le sql?
si
params ["type"] == 'produit'
vous obtiendrez l'erreur carsql
n'est pas défini. Est-ce le comportement souhaité? Que voulez-vous que votre fonction fasse dans ce cas? il ne peut pas faire d'action de curseursql
, voulez-vous que la fonction quitte et renvoie quelque chose?Vous pouvez ajouter une instruction
else
à la fin. Avec juste une séquence deif
etelif
s, il est toujours possible quesql
finisse par être indéfini.