Flask SQLAlchemy 存取.h5文件到数据库出现NoneType报错如何解决
报错根因
NoneType object has no attribute data报错是因为Stock.query.filter_by(symbol=str(stock.symbol) + 'Model.h5').first()返回了空值,未查询到匹配的记录。经确认,触发该问题的核心原因是代码运行在多线程环境下:Flask-SQLAlchemy的数据库会话默认是线程隔离的,不同线程之间的会话数据不共享,写入操作所在线程提交的记录,在读取操作的其他线程中可能未同步可见,或者你跨线程传递了未绑定到当前线程的Stock实例对象,导致读取失败。
解决方案
1. 线程内单独查询
所有数据库读写操作都在当前线程内独立执行,不要跨线程传递数据库实例对象,每次需要访问数据时在当前线程单独发起查询,同时增加空值判断避免直接报错:
# 读取操作调整示例 def get_h5_model(stock_symbol): # 当前线程内独立发起查询,不使用其他线程返回的Stock实例 target_symbol = f"{stock_symbol}Model.h5" stock_record = Stock.query.filter_by(symbol=target_symbol).first() if not stock_record: # 可根据业务需求调整兜底逻辑 raise Exception(f"未找到symbol为{target_symbol}的模型记录") with open('model.h5', "wb") as filehandler: filehandler.write(stock_record.data)
2. 会话生命周期管理
如果你使用了Flask-SQLAlchemy默认的scoped_session,每个线程完成数据库操作后调用db.session.remove()清理会话,避免会话残留导致的查询异常。
3. 写入校验
写入操作完成后可增加即时校验,确认数据写入成功:
# 写入操作调整示例 def save_h5_model(stock): target_symbol = f"{stock.symbol}Model.h5" with open('model.h5', 'rb') as filehandler: test = Stock( symbol=target_symbol, data=filehandler.read(), isStock=False ) db.session.merge(test) db.session.commit() # 写入后校验 verify_record = Stock.query.filter_by(symbol=target_symbol).first() assert verify_record is not None, "模型文件写入数据库失败"
字段说明
你当前定义的data = db.Column(db.LargeBinary(length=(2**32)-1))对应MySQL的LongBlob类型,单字段最大支持4GB存储,可正常存储.h5模型文件,无需调整字段定义。
内容的提问来源于stack exchange,提问作者syed2096
相关产品推荐
相关产品推荐

