如何将mongodump生成的BSON文件转换为Parquet格式?
解决BSON转JSON再转Parquet的实操问题
看起来你在BSON转JSON的环节踩了几个典型的坑,我来一步步帮你梳理解决:
先搞定核心报错:TypeError: a bytes-like object is required, not 'str'
这个报错的根源很明确——你打开BSON文件时用了文本模式("r"),但bson.decode_file_iter()需要读取二进制数据。BSON是二进制存储格式,必须用二进制模式打开文件。
完整的BSON→JSON→Parquet转换流程
1. 正确读取并解析BSON文件
用"rb"模式打开BSON文件,再通过decode_file_iter()生成器逐个解析文档:
from bson import decode_file_iter from bson.json_utils import dumps # 二进制模式打开BSON文件 with open("你的文件.bson", "rb") as bson_file: # 遍历生成器,逐个获取解析后的MongoDB文档(Python字典格式) for doc in decode_file_iter(bson_file): # 把文档转成带格式的JSON字符串(自动处理ObjectId等Mongo特殊类型) json_str = dumps(doc, ensure_ascii=False) print(json_str) # 也可以把文档收集到列表,后续批量处理 # docs.append(doc)
2. 批量保存为JSON Lines格式(方便后续转Parquet)
推荐用JSON Lines(每行一个JSON对象)的格式保存,比普通JSON更适合大数据量处理:
from bson import decode_file_iter from bson.json_utils import dumps with open("输入文件.bson", "rb") as bson_file, open("输出文件.jsonl", "w", encoding="utf-8") as json_file: for doc in decode_file_iter(bson_file): # 逐行写入JSON字符串 json_file.write(dumps(doc, ensure_ascii=False) + "\n")
3. JSON Lines转Parquet
用pandas结合pyarrow引擎完成转换,简单高效:
import pandas as pd # 读取JSON Lines文件 df = pd.read_json("输出文件.jsonl", lines=True) # 保存为Parquet格式 df.to_parquet("最终文件.parquet", engine="pyarrow")
解释你之前遇到的其他问题
- 生成器对象不会处理:
decode_file_iter()返回的是懒加载生成器,直接用for循环遍历就能逐个取出解析后的文档,不需要额外复杂操作。 - json_utils.dump得到乱码字符串:你应该是直接把未解析的BSON二进制字节传给了
dump方法,而不是先通过decode_file_iter()解析成Python字典。那些乱码其实是原始的BSON二进制数据,没有经过解析就被当成字符串处理了。
大数据量优化建议
如果你的BSON文件特别大,别一次性把所有文档加载到内存,而是边解析边写入,再分块转Parquet:
# 边解析BSON边写入JSON Lines with open("大文件.bson", "rb") as bson_file, open("大文件.jsonl", "w", encoding="utf-8") as json_file: for doc in decode_file_iter(bson_file): json_file.write(dumps(doc, ensure_ascii=False) + "\n") # 分块读取JSON Lines并追加写入Parquet chunk_size = 10000 for chunk in pd.read_json("大文件.jsonl", lines=True, chunksize=chunk_size): chunk.to_parquet("大文件.parquet", engine="pyarrow", append=True)
内容的提问来源于stack exchange,提问作者tanaka
相关产品推荐
相关产品推荐

