UnboundLocalError: variable local ‘cursor’ referenciada antes de la asignación

Así que soy un novato, pero estoy trabajando en un sistema de registro en matraz / MYSQL

Recibo este error (UnboundLocalError: variable local ‘cursor’ referenciada antes de la asignación)

Después de horas de jugar con el código e investigar necesito tu ayuda.

Este es mi archivo, por favor avíseme si hay algo más que deba compartir. gracias

from flask import Flask, render_template, json, request from flask.ext.mysqldb import MySQL from werkzeug import generate_password_hash, check_password_hash app = Flask(__name__) mysql = MySQL() app.config['MYSQL_DATABASE_USER'] = 'x' app.config['MYSQL_DATABASE_PASSWORD'] = 'x' app.config['MYSQL_DATABASE_DB'] = 'x' app.config['MYSQL_DATABASE_HOST'] = 'x' mysql.init_app(app) @app.route('/') def main(): return render_template('index.html') @app.route('/login') def login(): return render_template('login.html') @app.route('/showSignUp') def showSignUp(): return render_template('signup.html') @app.route('/signUp',methods=['POST','GET']) def signUp(): try: _name = request.form['inputName'] _email = request.form['inputEmail'] _password = request.form['inputPassword'] # validate the received values if _name and _email and _password: # All Good, let's call the MySQL conn = mysql.connect() cursor = conn.cursor() _hashed_password = generate_password_hash(_password) cursor.callproc('sp_createUser',(_name,_email,_hashed_password)) data = cursor.fetchall() if len(data) is 0: conn.commit() return json.dumps({'message':'User created successfully !'}) else: return json.dumps({'error':str(data[0])}) else: return json.dumps({'html':'Enter the required fields'}) except Exception as e: return json.dumps({'error':str(e)}) finally: cursor.close() conn.close() if __name__ == '__main__': app.run() 

Solo define conn y cursor dentro del bloque if que verifica los valores del formulario. Si no se ingresa el bloque, no están definidos, pero aún así intenta hacer referencia a ellos para cerrarlos de todos modos. Solo debes llamar a close en ambos si los has definido. Mueva conn = y cursor = a antes del bloque if, o mueva las llamadas close al bloque.

Sin embargo, el mayor problema es que estás malentendido / complicando demasiado cómo usar Flask-MySQLdb. Creará automáticamente la conexión y la cerrará cuando se realice la solicitud, lo que también cierra el cursor. Simplemente use la extensión como se describe en los documentos .

 ... cur = mysql.connection.cursor() cur.callproc('sp_createUser', (name, email, hashed_password)) data = cur.fetchall() ... 

Personalmente, recomendaría usar un administrador de contexto para manejar la apertura y el cierre de su cursor y conexión. Puede lograr esto de manera bastante simple y es más limpio y fácil de depurar. Esto también eliminaría el problema de intentar cerrar una conexión o un cursor antes de que se abra en su bloque gigante de prueba excepto.

 from contextlib import closing # do a bunch of stuff prior to opening connection with closing(mysql.connect()) as conn: with closing(conn.cursor()) as cursor: # do a bunch of stuff and don't worry about running .close() 

Puedes ver los documentos para closing aquí .

Usar el closing cambiaría tu código para ser algo como esto. Aunque podría usar más refactorización, pero esa es una pregunta para el sitio de revisión de código.

 from flask import Flask, render_template, json, request from flask.ext.mysqldb import MySQL from werkzeug import generate_password_hash, check_password_hash from contextlib import closing app = Flask(__name__) mysql = MySQL() app.config['MYSQL_DATABASE_USER'] = 'x' app.config['MYSQL_DATABASE_PASSWORD'] = 'x' app.config['MYSQL_DATABASE_DB'] = 'x' app.config['MYSQL_DATABASE_HOST'] = 'x' mysql.init_app(app) @app.route('/') def main(): return render_template('index.html') @app.route('/login') def login(): return render_template('login.html') @app.route('/showSignUp') def showSignUp(): return render_template('signup.html') @app.route('/signUp',methods=['POST','GET']) def signUp(): try: _name = request.form['inputName'] _email = request.form['inputEmail'] _password = request.form['inputPassword'] # validate the received values if _name and _email and _password: # All Good, let's call the MySQL with closing(mysql.connect()) as conn: with closing(conn.cursor()) as cursor: _hashed_password = generate_password_hash(_password) cursor.callproc('sp_createUser',(_name,_email,_hashed_password)) data = cursor.fetchall() if len(data) is 0: conn.commit() return json.dumps({'message':'User created successfully !'}) else: return json.dumps({'error':str(data[0])}) else: return json.dumps({'html':'Enter the required fields'}) except Exception as e: return json.dumps({'error':str(e)}) if __name__ == '__main__': app.run()