如何使用Python直接解析AWS S3上存储的gz文件,无需本地解压?
Python实现S3压缩CSV直接导入PostgreSQL方案
前置依赖
需要安装两个第三方库,gzip为Python标准库无需额外安装:
pip install boto3 psycopg2-binary
AWS凭证可通过环境变量、
~/.aws/credentials配置文件、运行环境的IAM角色三种方式自动读取,无需硬编码到代码中。
完整实现代码
全程内存流式处理,不会将gz文件下载到本地磁盘:
import boto3 import gzip import io import psycopg2 # 配置项,可根据批量迁移需求改为参数传入 CONFIG = { "s3_bucket": "你的S3存储桶名称", "s3_key": "gz文件在S3中的路径,例如 snowflake_export/user.csv.gz", "pg_table": "PostgreSQL目标表名", "csv_delimiter": ",", # 与Snowflake导出时指定的FIELD_DELIMITER保持一致 "skip_header": True, # CSV第一行为字段名时设为True "pg_conn": { "dbname": "数据库名", "user": "用户名", "password": "密码", "host": "PostgreSQL服务地址", "port": "5432" } } # 初始化S3客户端,流式读取gz文件 s3_client = boto3.client("s3") s3_resp = s3_client.get_object( Bucket=CONFIG["s3_bucket"], Key=CONFIG["s3_key"] ) s3_byte_stream = s3_resp["Body"] # 包装gzip流直接解压为文本流,无需落盘 with gzip.GzipFile(fileobj=s3_byte_stream, mode="rb") as gz_stream: # 大文件推荐用TextIOWrapper流式读取,避免占用过高内存 text_stream = io.TextIOWrapper(gz_stream, encoding="utf-8") # 连接PostgreSQL执行COPY导入 pg_conn = psycopg2.connect(**CONFIG["pg_conn"]) try: with pg_conn.cursor() as cur: cur.copy_from( file=text_stream, table=CONFIG["pg_table"], sep=CONFIG["csv_delimiter"], skiprows=1 if CONFIG["skip_header"] else 0, quote='"' # 与Snowflake导出时指定的FIELD_OPTIONALLY_ENCLOSED_BY保持一致 ) pg_conn.commit() except Exception as e: pg_conn.rollback() raise e finally: pg_conn.close()
注意事项
- 确保Snowflake导出CSV的字段顺序、字段类型与PostgreSQL目标表完全匹配,避免导入错位或类型报错
- 如果迁移的是批量表,将上述逻辑封装为函数,遍历S3对应前缀下的所有gz文件循环调用即可
- 运行程序的身份需要拥有对应S3对象的
s3:GetObject权限,以及PostgreSQL目标表的写入权限 - 处理GB级以上大文件时,
io.TextIOWrapper会边读边导入,内存占用始终保持在MB级,不会出现内存溢出问题
内容的提问来源于stack exchange,提问作者Anand Rajakrishnan
相关产品推荐
相关产品推荐

