更新数据时Flask-Mysql类型错误

时间:2017-09-07 09:44:20

标签: python mysql flask flask-mysql

当我用flask和package flask-mysql写一个网站时,我遇到了一个奇怪的错误。

这是bug函数的代码:

@app.route('/calendar/editeventtitle',methods=['POST'])
def editeventtitle():
    if not session.get('logged_in'):
      abort(401)

    try:
      id = request.form.get('id',type=int)
      title = request.form['title']
      color = request.form['color']
      delete = request.form.get('delete')
    except:
      pass

    conn = mysql.connect()
    cursor = conn.cursor()
    print(id,type(id))
    # try:
    #   print(delete,type(delete))
    # except:
    #   pass

    if id and delete:
        cursor.execute('delete from events where id = %d',id)
        conn.commit()
        flash('Event canceled!')
        return redirect(url_for('calendar'))
    elif id and title and color:
        cursor.execute('update events set title = %s, color = %s where id = %d',(title,color,id))
        conn.commit()
        flash('Event updated!')
        return redirect(url_for('calendar'))

当我将四个变量发布到此页面时。我成功地得到了他们。 print(id,type(id))的结果如下:

6 <class 'int'>

我们看到它确实是一个整数,但是当代码开始更新或删除db中的数据时,这里是错误消息:

  

TypeError:%d format:需要一个数字,而不是str

真的不知道原因= - =,谁能帮助我?谢谢。

PS:Python3.6.1,Flask 0.12.2,Flask-Mysql 1.4.0

1 个答案:

答案 0 :(得分:3)

您应该使用%s来执行您执行的SQL查询中的所有参数。原因是flask-mysql(或它所依赖的任何MySQL Python库)会在进行字符串插值之前将您提供的参数title, color, id转换为字符串。

它之所以这样做,是因为它还会检查您在查询中使用的任何参数是否是预期类型的​​实际合理参数,例如整数,SQL标识符,而不是可能破坏查询的SQL代码片段。 (这用于获取对数据库的未授权访问,称为SQL注入)。对于每个值,它将检查类型并决定如何将其转换为SQL表示。

这就是为什么您不需要围绕参数titlecolor的单引号。 SQL库将参数标识为字符串并添加引号,同时还可以转义这些字符串中包含的任何单引号。这也是为什么你可以在这里传递像datetime这样的Python对象的原因。该对象将被正确转换为相应SQL类型的文字表示。