【发布时间】: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 forexecute。查询的结果总是至少在游标中被引用,因此c.execute*(); c.fetch*()将适用于任何符合 DBAPI2 的模块。 -
@albert:看看这个:stackoverflow.com/questions/30421466/…
标签: python mysql mysql-connector mysql-connector-python