Databricks环境下Python迁移S3 jsonl.gz到ABS并解压报错求助
问题修复方案
报错根因
boto3的get_object接口返回值是包含响应元数据的字典,不是文件流对象,你直接将该字典传入pd.read_json、gzip.open才会触发<class 'dict'>类型不兼容报错,S3文件的实际二进制流存储在返回字典的['Body']字段中。
同时还有3处逻辑问题需要修正:
- 你的源文件是
jsonl(每行一个JSON对象)格式,用pandas读取时需要指定lines=True参数 - 不能直接对DataFrame对象执行
write操作,需要先将其转成JSON字符串格式 - 挂载的ABS容器写入路径需要替换为你实际的挂载点路径,不能直接写容器名
修正后代码(两种场景可选)
场景1:无需处理数据,直接将S3的gz文件解压后写入ABS(性能最优,无内存压力)
fileun = dbutils.widgets.get("fileun") directory = dbutils.widgets.get("directory") # 解压后的文件名 target_filename = fileun[:-3] s3_file_key = directory + fileun # 替换为你实际的ABS容器挂载路径,比如你把ABS挂载到/mnt/my_abs/就填这个前缀 abs_mount_path = "/mnt/替换为你的ABS挂载点名称/" target_file_path = abs_mount_path + target_filename import boto3 import gzip import shutil client = boto3.client( "s3", region_name='你的实际region', aws_access_key_id='你的AK', aws_secret_access_key='你的SK' ) response = client.get_object( Bucket='你的S3桶名', Key=s3_file_key ) # 直接用S3返回的流做解压,写入ABS挂载路径 with gzip.open(response['Body'], 'rb') as f_in: with open(target_file_path, 'wb') as f_out: shutil.copyfileobj(f_in, f_out)
场景2:需要读取为DataFrame做数据处理后再写入ABS
fileun = dbutils.widgets.get("fileun") directory = dbutils.widgets.get("directory") target_filename = fileun[:-3] s3_file_key = directory + fileun abs_mount_path = "/mnt/替换为你的ABS挂载点名称/" target_file_path = abs_mount_path + target_filename import pandas as pd import boto3 import gzip client = boto3.client( "s3", region_name='你的实际region', aws_access_key_id='你的AK', aws_secret_access_key='你的SK' ) response = client.get_object( Bucket='你的S3桶名', Key=s3_file_key ) # 读取为DataFrame,指定lines=True适配jsonl格式 with gzip.open(response['Body'], 'rb') as f: df = pd.read_json(f, lines=True) # ------------------- 这里可以加你需要的DataFrame处理逻辑 ------------------- # 处理完成后写回ABS,保持jsonl格式 df.to_json(target_file_path, orient='records', lines=True, force_ascii=False)
注意事项
- 请提前确认ABS容器的挂载路径有写入权限
- 如果单文件过大,建议优先用场景1的流拷贝方案,避免Driver节点内存溢出
- boto3的AK/SK建议不要硬编码在代码中,可以用Databricks的Secrets管理器存储调用
内容的提问来源于stack exchange,提问作者Aaron Dupaix
相关产品推荐
相关产品推荐

