2015-09-10 122 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

相關問題