You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为何pymysql cursor.execute()执行后得到不同结果?

解决Flask+MySQL中cursor.execute()结果不一致的问题

我来帮你捋捋这个cursor.execute()结果不一致的问题,结合你用的Flask 0.12.2和Python 3.6.2版本,大概率是这几个常见坑导致的,一个个来排查:

1. 游标类型不匹配导致返回格式异常

flaskext.mysql默认用的是普通游标,查询返回的是元组列表,如果你期望的是字典格式(键对应字段名),就会觉得“结果不对”。解决方法是指定DictCursor

from pymysql.cursors import DictCursor

# 建立连接时指定游标类型
con = mysql.connect(cursorclass=DictCursor)
cursor = con.cursor()

这样执行fetchall()后,返回的是字典列表,和你预期的字段对应关系一致,不会出现“结果结构不对”的错觉。

2. 事务未提交导致数据不一致

如果你的操作涉及增删改,却没提交事务,同一个连接里的查询可能看不到最新修改,不同连接之间的查询结果也会有差异。一定要记得在写入操作后提交:

cursor.execute("INSERT INTO your_table (col1) VALUES (%s)", ("value1",))
con.commit()  # 关键步骤,别漏!

要是你做的是只读查询,可以直接开启自动提交,避免事务隔离级别带来的影响:

con.autocommit(True)

3. 游标重复使用未重置导致结果混乱

同一个游标如果多次执行查询,但没把上一次的结果读完,后续的execute结果会和预期不符。建议每次查询用新游标,用完就关闭:

# 每次查询都初始化新游标
cursor = con.cursor()
cursor.execute("SELECT * FROM your_table")
result = cursor.fetchall()
cursor.close()  # 用完就关,避免残留数据干扰

4. SQL语句参数化错误导致查询结果异常

如果你用字符串拼接写SQL,很容易因为特殊字符、参数格式问题导致查询结果不符合预期,还会有SQL注入风险。一定要用参数化查询:

# 错误示例:字符串拼接,容易出问题
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
# 正确示例:参数化,安全又可靠
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))

完整示例代码

把上面的注意点整合起来,给你一个可参考的完整实现:

from flask import Flask, jsonify
from flaskext.mysql import MySQL
from pymysql.cursors import DictCursor

app = Flask(__name__)

# 数据库配置
app.config['MYSQL_DATABASE_PORT'] = 3306
app.config['MYSQL_DATABASE_USER'] = 'your_username'
app.config['MYSQL_DATABASE_PASSWORD'] = 'your_password'
app.config['MYSQL_DATABASE_DB'] = 'your_db_name'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'

mysql = MySQL()
mysql.init_app(app)

@app.route('/query-data')
def query_data():
    con = None
    cursor = None
    try:
        # 建立连接并指定字典游标
        con = mysql.connect(cursorclass=DictCursor)
        con.autocommit(True)  # 只读场景开启自动提交
        cursor = con.cursor()
        
        # 参数化查询示例
        cursor.execute("SELECT * FROM users WHERE status = %s", ("active",))
        result = cursor.fetchall()
        
        return jsonify({"success": True, "data": result})
    except Exception as e:
        return jsonify({"success": False, "error": str(e)}), 500
    finally:
        # 确保资源释放
        if cursor:
            cursor.close()
        if con:
            con.close()

if __name__ == '__main__':
    app.run(debug=True)

排查的时候还可以打印cursor.rowcount看看影响的行数,或者直接打印fetchall()的结果,确认是格式问题还是数据本身的问题。

内容的提问来源于stack exchange,提问作者puerdon

火山引擎 最新活动