2015-09-10 38 views
2

所以我是新手,但在烧瓶中登记系统表单上的工作/ MYSQLUnboundLocalError:局部变量“游标”分配之前引用

我接收到该错误(UnboundLocalError:局部变量“游标”分配之前引用的)

后与代码和研究打个小时,我需要你的帮助。

这是我的文件,请让我知道如果那里有什么事我需要共享。 谢谢

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':'<span>Enter the required fields</span>'}) 

    except Exception as e: 
     return json.dumps({'error':str(e)}) 
    finally: 
     cursor.close() 
    conn.close() 

if __name__ == '__main__': 
    app.run() 

回答

5

你只定义conncursor IF块检查表单值内。如果该块没有被输入,它们没有被定义,但你仍然试图引用它们来关闭它们。如果您已经定义了它们,则只应该拨打close。将conn =cursor =移至if块之前,或将close调用移至该块内。

然而,更大的问题是,你误解/过于复杂如何使用瓶,MySQLdb的。它会自动创建连接并在请求完成时将其关闭,并关闭游标。只需使用docs中所述的扩展名即可。

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

个人而言,我会建议使用上下文管理器来处理你的光标和连接的开启和关闭。你可以简单地实现这一点,它更清洁,更易于调试。这也可以消除尝试关闭连接或游标之前,在您的巨型尝试除外块打开之前的问题。

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() 

您可以查看文档的closinghere

使用closing会改变你的代码是这样的。虽然它可以使用更多的重构,但这是代码评论网站的问题。

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':'<span>Enter the required fields</span>'}) 

    except Exception as e: 
     return json.dumps({'error':str(e)}) 

if __name__ == '__main__': 
    app.run() 
+0

因此,我删除我的最终代码,直到if __name__并将它替换为您的注释之间的代码并导入上下文库? –

+0

是的,删除finally语句并导入该库,并将打开的语句更改为with语句,您应该很好。 – electrometro

+0

这完全没有必要,当请求上下文结束时,Flask-MySQLdb关闭连接(它也关闭游标)。事实上,即使创建连接也是多余的。 – davidism

相关问题