python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python数据导出到Excel

Python实现Redshift数据高效导出到Excel文件的多Sheet

作者:weixin_30777913

本文将手把手教你使用Python从本地Parquet读取数据,再通过Redshift UNLOAD导出到S3并下载为DataFrame,最后将两个DataFrame按id排序后写入同一个Excel文件的不同Sheet,感兴趣的小伙伴可以了解下

下面结合Python及相关库(pandas、redshift_connector、awswrangler、openpyxl、boto3、pathlib 和 datetime)实现从本地读取Parquet文件、从Amazon Redshift导出数据到S3并下载、合并 两个DataFrame并按指定列排序后导出至Excel文件(一个文件多个Sheet)的完整数据工程流程,并展开详细论述。所有涉及的库与实现思路均可在生产环境或数据分析项目中直接复用。

1. 环境准备

首先安装所需依赖包,并导入相关库:

pip install pandas pyarrow redshift_connector awswrangler openpyxl boto3
import os
import pandas as pd
import redshift_connector
import awswrangler as wr
import boto3
from datetime import datetime
from pathlib import Path

2. 从本地Parquet读取DataFrame(df_1)

利用 pandas.read_parquet 从本地读取parquet文件并将其加载为DataFrame:

parquet_path = "./data/source_data.parquet"
df_1 = pd.read_parquet(parquet_path, engine="pyarrow")

read_parquet 默认使用 pyarrow 引擎,该引擎对列式存储的parquet文件有较好的性能表现。在处理大规模数据时,可通过设置 use_threads=True 启用多线程读取,或通过 memory_map=True 使用内存映射文件以提升读取速度。

3. 从Amazon Redshift通过UNLOAD导出数据到S3并下载为DataFrame(df_2)

此部分整合了 redshift_connector、awswrangler、boto3、pathlib 和 datetime 等库的功能。

3.1 建立Redshift连接

使用 redshift_connector 创建与Amazon Redshift集群的连接:

conn = redshift_connector.connect(
    host=os.getenv("REDSHIFT_HOST"),
    database=os.getenv("REDSHIFT_DATABASE"),
    port=int(os.getenv("REDSHIFT_PORT", 5439)),
    user=os.getenv("REDSHIFT_USER"),
    password=os.getenv("REDSHIFT_PASSWORD")
)

此方式基于AWS凭证进行认证,符合Amazon Redshift Python连接器的标准用法。

3.2 利用awswrangler执行UNLOAD操作

awswrangler.redshift.unload_to_files 封装了Redshift的 UNLOAD 命令,可将查询结果直接导出至S3(支持CSV或Parquet格式),适用于大规模数据导出场景。

使用带时间戳的S3路径以规避文件名冲突:

timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
s3_unload_path = f"s3://your-bucket/redshift_unload/{timestamp}/"
sql_query = """
SELECT 
    id,
    column_a,
    column_b,
    created_at
FROM your_schema.your_table
WHERE created_at>= '2026-01-01'
"""
wr.redshift.unload_to_files(
    sql=sql_query,
    path=s3_unload_path,
    con=conn,
    iam_role=os.getenv("REDSHIFT_IAM_ROLE"),
    unload_format="PARQUET",
    parallel=True,
    region=os.getenv("AWS_REGION", "us-east-1")
)

UNLOAD路径设计说明:通过在S3路径中嵌入 datetime.now().strftime("%Y%m%d_%H%M%S") 生成的时间戳,可确保每次运行生成唯一路径,防止多次执行之间的文件覆盖。也可在UNLOAD命令中使用 ALLOWOVERWRITE 参数覆盖已有文件,但通过时间戳隔离版本是更为稳健的做法。

参数说明:

3.3 从S3下载并读取为DataFrame

UNLOAD执行完毕后,使用 boto3 列出S3路径下生成的文件,并通过 awswrangler.s3.read_parquet 直接读取S3上的parquet文件为DataFrame:

session = boto3.Session(region_name=os.getenv("AWS_REGION", "us-east-1"))
df_2 = wr.s3.read_parquet(path=s3_unload_path, boto3_session=session)

awswrangler.s3.read_parquet 可以自动识别S3路径下的所有parquet文件并将它们合并为单个DataFrame,极大简化了S3数据读取流程。

3.4 关闭Redshift连接

conn.close()

4. 统一按id列排序

两个DataFrame均按照 id 列升序排列,以确保写入Excel后的数据具备一致性:

df_1 = df_1.sort_values(by="id", ascending=True, ignore_index=True)
df_2 = df_2.sort_values(by="id", ascending=True, ignore_index=True)

ignore_index=True 可重置索引,避免将旧索引带入Excel输出。

5. 将两个DataFrame写入同一Excel文件的不同Sheet

使用 pd.ExcelWriter 配合 openpyxl 引擎(支持 .xlsx 格式),将两个DataFrame分别写入不同Sheet:

output_path = Path("./output/mult_sheets_1.xlsx")
output_path.parent.mkdir(parents=True, exist_ok=True)
with pd.ExcelWriter(output_path, engine="openpyxl") as writer:
    df_1.to_excel(writer, sheet_name="df_1", index=False)
    df_2.to_excel(writer, sheet_name="df_2", index=False)

with 语句可确保Excel文件在写入完成后自动保存并关闭。sheet_name 分别设置为 "df_1" 和 "df_2",index=False 避免将行索引写入Excel。如需在同一文件内写入更多DataFrame,只需继续调用 to_excel 方法即可。

6. 完整代码示例

将上述各模块整合为完整可运行的代码:

import os
import pandas as pd
import redshift_connector
import awswrangler as wr
import boto3
from datetime import datetime
from pathlib import Path
# ---------- 配置 ----------
parquet_path = "./data/source_data.parquet"
output_path = Path("./output/mult_sheets_1.xlsx")
output_path.parent.mkdir(parents=True, exist_ok=True)
sql_query = """
SELECT 
    id,
    column_a,
    column_b,
    created_at
FROM your_schema.your_table
WHERE created_at>= '2026-01-01'
"""
# ---------- 1. 读取本地Parquet(df_1) ----------
df_1 = pd.read_parquet(parquet_path, engine="pyarrow")
# ---------- 2. 连接Redshift ----------
conn = redshift_connector.connect(
    host=os.getenv("REDSHIFT_HOST"),
    database=os.getenv("REDSHIFT_DATABASE"),
    port=int(os.getenv("REDSHIFT_PORT", 5439)),
    user=os.getenv("REDSHIFT_USER"),
    password=os.getenv("REDSHIFT_PASSWORD")
)
# ---------- 3. UNLOAD到S3 ----------
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
s3_unload_path = f"s3://your-bucket/redshift_unload/{timestamp}/"
wr.redshift.unload_to_files(
    sql=sql_query,
    path=s3_unload_path,
    con=conn,
    iam_role=os.getenv("REDSHIFT_IAM_ROLE"),
    unload_format="PARQUET",
    parallel=True,
    region=os.getenv("AWS_REGION", "us-east-1")
)
# ---------- 4. 从S3读取为DataFrame(df_2) ----------
session = boto3.Session(region_name=os.getenv("AWS_REGION", "us-east-1"))
df_2 = wr.s3.read_parquet(path=s3_unload_path, boto3_session=session)
# ---------- 5. 关闭Redshift连接 ----------
conn.close()
# ---------- 6. 按id排序 ----------
df_1 = df_1.sort_values(by="id", ascending=True, ignore_index=True)
df_2 = df_2.sort_values(by="id", ascending=True, ignore_index=True)
# ---------- 7. 写入Excel ----------
with pd.ExcelWriter(output_path, engine="openpyxl") as writer:
    df_1.to_excel(writer, sheet_name="df_1", index=False)
    df_2.to_excel(writer, sheet_name="df_2", index=False)
print(f"Excel文件已生成:{output_path}")

7. 常见问题与调试建议

7.1 UNLOAD权限错误

执行UNLOAD时若遇到 AccessDenied 错误,请检查 iam_role 对应的IAM角色是否具备以下权限:

7.2 区域不匹配

若S3桶与Redshift集群位于不同AWS区域,需通过 region 参数明确指定S3桶所在区域,否则UNLOAD将失败。

7.3 时间戳路径覆盖问题

如需在同一路径下多次运行,建议保留时间戳前缀,避免使用 ALLOWOVERWRITE 参数以防止意外覆盖历史数据。同时可在脚本末尾添加S3清理逻辑,定期删除过期的UNLOAD临时文件以控制存储成本。

7.4 性能优化建议

UNLOAD并行度:parallel=True 可显著提升大数据量的导出速度,但如果后续处理对文件顺序有严格要求,可设置 parallel=False 并按 ORDER BY 子句生成单一有序文件。

Parquet读取:若 df_2 数据量极大,可使用 wr.s3.read_parquet 的 chunked=True 参数实现分块读取,降低内存压力。

内存映射:对于本地parquet文件的读取,可通过 pd.read_parquet(..., memory_map=True) 减少内存开销。

8. 扩展建议

以上流程可作为日常数据分析 或ETL任务的基础模板。如需进一步工程化,可考虑:

此方案覆盖了从本地数据读取、云端数据仓库导出、云存储中转、本地合并到最终Excel输出的全链路,适用于数据分析报告生成、数据质量比对、多源数据融合等业务场景。

以上就是Python实现Redshift数据高效导出到Excel文件的多Sheet的详细内容,更多关于Python数据导出到Excel的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文