在Flask应用中使用Pandas DataFrame作为只读表是否具备可扩展性?
直接在内存中加载Pandas DataFrame处理Flask请求是否可行?
问题描述
我正在开发一个小型Flask网站,依赖CSV文件的数据,通过JQuery在前端表格展示数据。用户在前端下拉框选择ID后,后端会执行函数,用该ID过滤数据并返回,通常仅返回DataFrame的单列数据。
常规做法是在启动时将CSV数据加载到SQLite数据库,运行时用Python的SQL方法查询。但我的数据表格大小为15MB(214K行),且在应用生命周期内不会更新。
因此,我想了解直接将DataFrame加载到内存,在请求到来时过滤副本是否更简便?这种方式是否具备可扩展性,还是只是暂时规避问题?
示例代码:
app = Flask(__name__) dir_path = os.path.abspath(os.path.dirname(__file__)) with app.app_context(): print("Writing DB on startup") query_df = pd.read_csv(dir_path+'/query_file.csv') @app.route('/getData', methods=["POST"]) def get_data(): id = request.get_json() print("Getting rows....") data_list = sorted(set(query_df[query_df['ID'] == id]['Name'].tolist())) return jsonify({'items': data_list, 'ID': id})
回答
结论:你的方案完全可行,且是当前场景下的合理选择
1. 直接加载DataFrame确实更简便
- 15MB的数据集在内存中占用极小(Pandas DataFrame的内存占用通常仅比原始CSV略高,214K行完全不会造成内存压力),启动时一次性加载即可,无需额外维护SQLite的数据库创建、表结构映射等工作。
- 代码逻辑更简洁:不需要编写SQL查询、处理数据库连接,直接用Pandas的原生过滤语法就能完成需求,减少了额外的出错点。
2. 关于可扩展性的判断
- 如果你的业务长期保持数据不更新、请求量不大(比如单服务器可承载的几百QPS以内),这种方式不存在“暂时规避问题”的说法,是完全稳定的方案。
- 只有当未来出现以下情况时,才需要考虑切换到数据库:
- 数据量大幅增长到GB级别,内存无法容纳;
- 需要多进程/多服务器部署(此时每个进程都会加载一份DataFrame,会造成内存浪费);
- 数据需要动态更新(内存中的数据无法实时同步,必须依赖数据库做持久化)。
3. 当前代码的优化建议
- 提前预处理数据:把按ID分组、去重排序的工作放在启动时完成,避免每次请求都重复计算,提升响应速度:
from collections import defaultdict app = Flask(__name__) dir_path = os.path.abspath(os.path.dirname(__file__)) id_to_names = defaultdict(list) with app.app_context(): query_df = pd.read_csv(dir_path+'/query_file.csv') # 按ID分组收集Name for id_val, name in query_df[['ID', 'Name']].itertuples(index=False): id_to_names[id_val].append(name) # 预做去重+排序 for k in id_to_names: id_to_names[k] = sorted(list(set(id_to_names[k]))) @app.route('/getData', methods=["POST"]) def get_data(): # 注意:这里要从JSON中取出具体的id字段,而非直接拿整个JSON对象 req_data = request.get_json() req_id = req_data.get('id') data_list = id_to_names.get(req_id, []) return jsonify({'items': data_list, 'ID': req_id}) - 修正请求参数获取逻辑:原代码中
id = request.get_json()会拿到整个JSON对象,若前端传的是{"id": "xxx"},需要通过键名取出具体的ID值,否则会导致过滤条件不匹配。
内容的提问来源于stack exchange,提问作者GreenGodot
相关产品推荐
相关产品推荐

