【问题标题】:MySQL-Python connector attribute error for cursor object游标对象的 MySQL-Python 连接器属性错误
【发布时间】:2019-02-23 08:04:24
【问题描述】:

我正在将 mysql-connector-python 包用于 Flask 中的一个项目。对于注册路由部分,我希望 MySQL 检查用户名是否已经存在,如果存在,我将设置一个错误。我的代码如下所示:

@bp.route('/signup', methods=('POST',))
def signup():

    ...

    username = reqObj["username"]
    password = reqObj["password"]
    error = None

    db = get_db()
    cursor = db.cursor()
    query = ("SELECT * FROM userinfo " 
        "WHERE username=%s")

    existingUser = cursor.execute(query, (username,)).fetchone()

    if existingUser is not None:
        error = "Username already exists"

    if error is None:
        cursor.execute(
            'INSERT INTO userinfo (username, password) VALUES (%s, %s)',
            (username, generate_password_hash(password))
        )

        cursor.close()
        db.commit()

        res = {'actionSuccess': True}
        return jsonify(res)
    else:
        res = {'actionSuccess': False, 'error': error}
        return jsonify(res)

get_db() 函数返回 mysql.connector.connect() 对象。但是,当我在服务器上运行它并对其进行测试时,我在 Flask 中收到错误消息:

...
existingUser = cursor.execute(query, (username,)).fetchone()
AttributeError: 'NoneType' object has no attribute 'fetchone'

所以我认为我的错误出在 cursor.execute() 的某个地方,我猜它返回的是 NoneType。所以我删除了 fetchone() 函数并重试,但现在我得到了这个错误:

...
File "e:\flasktest2\lib\site-packages\mysql\connector\connection.py", line 1128, in handle_unread_result
    raise errors.InternalError("Unread result found")
mysql.connector.errors.InternalError: Unread result found

这更加令人困惑,因为它现在说有未读结果,而刚才 cursor.execute() 是一个 NoneType。我不知道是什么导致了错误。然后我尝试注释掉整个 SELECT 查询部分,然后测试一下 INSERT 是否可以工作,果然可以。是什么导致了我的错误?

【问题讨论】:

  • 您在query = ("SELECT * FROM userinfo " "WHERE username=%s") 处违反了声明。试试这样的query = ("SELECT * FROM userinfo WHERE username=%s")
  • 显然 execute() 在 mysql.connector 游标对象上返回 None,除非它被 multi=True 调用。尝试cursor.execute(query, (username,)),然后分别尝试existingUser = cursor.fetchone()。至于Unread results found,这是here 的一些解释。
  • @shmee 嘿,是的,我自己才想出来的!由于某种原因,cursor.execute() 将完成操作,返回 None,然后将结果存储在游标对象本身中。所以我必须在游标 obj 上使用 fetchone,而不是在 cursor.execute()
  • 这种行为似乎在模块之间有所不同。使用sqlite3 完全可以使用cursor.execute(<SQL>).fetchone(),因为execute 返回调用它的游标对象。在pymysql 中,execute 返回受影响的行数。 PEP 249 does not define return values for execute。查询的结果总是至少在游标中被引用,因此c.execute*(); c.fetch*() 将适用于任何符合 DBAPI2 的模块。
  • @albert:看看这个:stackoverflow.com/questions/30421466/…

标签: python mysql mysql-connector mysql-connector-python


【解决方案1】:

显然,使用 mysql 连接器,无论执行语句的结果如何,cursor.execute(...) 都将返回 None。但是,结果将存储在游标对象本身中,即使结果是空集。在使用游标在新连接上执行新语句之前,您还必须获取当前查询的所有结果。这意味着:

cursor.execute(...)
cursor.fetchone()

相对于:

cursor.execute(...).fetchone()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-23
    • 2019-05-05
    • 2019-10-16
    • 2021-05-03
    • 2020-07-02
    • 2015-03-08
    • 1970-01-01
    • 2014-05-14
    相关资源
    最近更新 更多