You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重构后遇TypeError:'Connection'对象不可下标访问的问题排查

TypeError: 'Connection' object is not subscriptable 错误排查与解决

错误信息

File "/Applications/MAMP/htdocs/evahub/backend/rest_delete.py", line 23, in deleteDocument
    user = getDbUser(username)
  File "/Applications/MAMP/htdocs/evahub/backend/db_users_broker.py", line 25, in getDbUser
    usersCollection = db["users"]
TypeError: 'Connection' object is not subscriptable

相关代码

rest_delete.py 片段

...
user = getDbUser(username)
...

db_users_broker.py

from db_config import getDb

db = getDb()
def getDbUser(username):
    usersCollection = db["users"]
    uq = {"username": username}

    user = usersCollection.find_one(uq)
    if user == None:
        return None
    else:
        return user

db_config.py

from flaskext.mysql import MySQL
from flask import Flask

app = Flask(__name__)

app.config["MYSQL_DATABASE_USER"] = "root"
app.config["MYSQL_DATABASE_PASSWORD"] = "root"
app.config["MYSQL_DATABASE_DB"] = "evahub"
app.config["MYSQL_DATABASE_HOST"] = "localhost"


def getDb():
    mysql = MySQL(
        app,
        prefix="",
        host=app.config["MYSQL_DATABASE_HOST"],
        user=app.config["MYSQL_DATABASE_USER"],
        password=app.config["MYSQL_DATABASE_PASSWORD"],
        db=app.config["MYSQL_DATABASE_DB"],
        autocommit=True,
    )
    connection = mysql.connect()
    return connection

错误原因

  1. API逻辑混淆:你当前使用flaskext.mysql操作MySQL数据库,但代码完全沿用了MongoDB的操作风格:
    • db["users"]是MongoDB中获取集合的写法,而MySQL的Connection对象不支持下标操作,因此触发TypeError。
    • usersCollection.find_one(uq)是MongoDB的查询方法,MySQL没有对应API,必须用SQL语句实现查询。
  2. 连接初始化冗余:getDb()每次调用都会重新创建MySQL实例,且全局赋值db = getDb()会导致连接长期占用,容易引发超时或资源泄漏问题。

解决方案

1. 优化数据库连接初始化(db_config.py)

全局仅初始化一次MySQL实例,避免重复创建资源:

from flaskext.mysql import MySQL
from flask import Flask

app = Flask(__name__)

app.config["MYSQL_DATABASE_USER"] = "root"
app.config["MYSQL_DATABASE_PASSWORD"] = "root"
app.config["MYSQL_DATABASE_DB"] = "evahub"
app.config["MYSQL_DATABASE_HOST"] = "localhost"

# 全局初始化一次MySQL实例
mysql = MySQL(app)

def getDb():
    return mysql.connect()

2. 重写用户查询逻辑(db_users_broker.py)

改用MySQL的SQL查询语法,替换MongoDB风格代码:

from db_config import getDb

def getDbUser(username):
    # 每次查询时临时获取连接,用完立即关闭
    connection = getDb()
    # 开启字典游标,让返回结果与MongoDB文档格式一致(键值对)
    cursor = connection.cursor(dictionary=True)
    
    # 参数化SQL查询,避免SQL注入
    query = "SELECT * FROM users WHERE username = %s"
    cursor.execute(query, (username,))
    
    # 获取单条结果,对应MongoDB的find_one方法
    user = cursor.fetchone()
    
    # 释放资源
    cursor.close()
    connection.close()
    
    return user

关键说明

  • MySQL中没有“集合”概念,对应的是数据表,必须通过SQL语句操作数据。
  • 不要全局保存数据库连接,应遵循“即用即取、用完即关”的原则,避免连接超时或资源浪费。
  • 使用参数化查询(%s占位符)是MySQL操作的安全规范,能有效防止SQL注入风险。

内容的提问来源于stack exchange,提问作者The Outstanding Question Asker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 08:38:12