如何将CSV嵌套列表列转SQLite关系库及解决读取后列表变字符串问题
问题1:CSV读写后嵌套列表索引失效的原因与解决
失效的核心原因是CSV格式本身不支持存储原生Python列表对象:
- 读取JSON时,pandas会自动把JSON内的嵌套结构解析为原生
list类型,支持切片索引- 写入CSV时,格式本身仅能存储纯文本,会把原本的list对象直接转成字符串字面量落盘;你看到的输出和原列表文本完全一致,只是字符串的展示效果,实际数据类型已经从
list变成了str
此时执行data['fermentables'][0][0],本质是对字符串取第0位字符,自然只能拿到开头的[。
如果必须通过CSV做数据中转,读取CSV时需要手动将字符串形式的列表转回原生类型,代码示例:
import ast import pandas as pd # 读取时指定转换规则,批量把字符串化的列表转回Python原生结构 df = pd.read_csv( "beer_recipes.csv", converters={ # 所有存了嵌套列表的列都可以在这里补充转换规则 "fermentables": ast.literal_eval, "hops": ast.literal_eval, "yeasts": ast.literal_eval } )
转换完成后,列内数据恢复为list类型,即可正常使用嵌套索引。
问题2:适配SQLite的嵌套结构转换实现
关系型数据库的核心设计原则是不存储嵌套集合结构,需要把一对多的嵌套关系拆分为独立的关联表,才能支撑后续的聚合统计查询。
推荐表结构设计
针对当前啤酒配方场景,拆分为两张核心关联表即可覆盖需求:
- 配方主表
recipes:存储每个啤酒配方的基础信息,设置recipe_id为唯一主键,其余字段存储配方名称、出酒量、酿造温度等无嵌套的独立参数 - 发酵原料明细表
fermentable_items:存储每个配方对应的单条发酵原料记录,字段结构为:id:自增主键recipe_id:外键,关联recipes表的recipe_idweight:对应子列表第0位的原料重量值grain_name:对应子列表第1位的谷物名称ppg:对应子列表第2位的原料潜在比重值deg_litner:对应子列表第3位的原料色度值grain_bill:对应子列表第4位的原料配方占比
实现流程
- 第一步:从原始JSON数据中提取所有非嵌套字段,生成独立的配方主表数据,为每一行配方分配唯一的
recipe_id - 第二步:逐行遍历每个配方的
fermentables嵌套列表,将每个子列表按照字段映射拆分为独立的单条原料记录,给每条记录绑定对应配方的recipe_id,汇总形成发酵原料明细表 - 第三步:将两张表直接通过pandas的
to_sql方法写入SQLite,无需经过CSV中转
常用查询示例
表结构拆分完成后,“查询所有啤酒配方中最常用谷物名称”的需求可直接通过标准SQL实现:
-- 统计每个谷物出现在多少个配方中,按出现次数倒序排列 SELECT grain_name, COUNT(DISTINCT recipe_id) AS used_recipe_count FROM fermentable_items GROUP BY grain_name ORDER BY used_recipe_count DESC;
内容的提问来源于stack exchange,提问作者Basalty
相关产品推荐
相关产品推荐

