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

在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 12:12:38