I'm using the mysql-connector-python package for a project in Flask. For the signup routing portion, I want MySQL to check if a username already exists, and if it does, I'll set an error. My code looks like this:
@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)
The get_db() function returns the mysql.connector.connect() object. However, when I run this on a server and test it, I get an error in Flask saying:
...
existingUser = cursor.execute(query, (username,)).fetchone()
AttributeError: 'NoneType' object has no attribute 'fetchone'
So I figure my error is somewhere with my cursor.execute(), which I'm guessing is returning a NoneType. So I delete the fetchone() function and try again, but now I get this error instead:
...
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
This is confusing even further, because it's now saying that there are unread results, when a moment ago the cursor.execute() was a NoneType. I don't know what's causing the error. I then tried commenting out the whole SELECT query section, and just tested to see if the INSERT would work, and sure enough it did. What's causing my errors?
query = ("SELECT * FROM userinfo " "WHERE username=%s"). try something like thisquery = ("SELECT * FROM userinfo WHERE username=%s")execute()on a mysql.connector Cursor object returnsNoneunless it is called withmulti=True. Trycursor.execute(query, (username,))and thenexistingUser = cursor.fetchone()individually. As for theUnread results found, this is somehwat explained here.sqlite3it is perfectly fine to docursor.execute(<SQL>).fetchone()becauseexecutereturns the cursor object it is called from. Inpymysql,executereturns the number of affected rows. PEP 249 does not define return values forexecute. The result of a query is always at least referenced in the cursor, so thatc.execute*(); c.fetch*()will work with any DBAPI2 compliant module.