You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何用Python从S3 Browser批量导入多份.csv至MySQL?

从S3批量导入CSV文件及文件夹到MySQL的解决方案

前提准备

  • 安装依赖包:pip install boto3 pymysql pandas
  • 确认AWS账号拥有S3桶的GetObject和ListBucket权限,MySQL账号具备目标数据库、表的写入权限
  • 提前确认MySQL目标表结构与CSV字段匹配,或允许代码自动创建表

核心实现步骤

1. 配置连接参数

import boto3
import pymysql
import pandas as pd
from io import StringIO

# S3配置
s3_bucket = "你的桶名称"
s3_folder_path = "csv文件所在的S3前缀/"  # 遍历整个桶则留空

# MySQL配置
mysql_host = "你的MySQL主机地址"
mysql_user = "MySQL用户名"
mysql_password = "MySQL密码"
mysql_db = "目标数据库名"

2. 遍历S3中所有CSV文件(含子文件夹)

s3_client = boto3.client('s3')

def get_all_s3_csv_files(bucket, prefix):
    csv_files = []
    # 分页遍历S3对象,避免单次请求返回数据过多
    paginator = s3_client.get_paginator('list_objects_v2')
    for page in paginator.paginate(Bucket=bucket, Prefix=prefix):
        for obj in page.get('Contents', []):
            if obj['Key'].endswith('.csv'):
                csv_files.append(obj['Key'])
    return csv_files

target_csv_files = get_all_s3_csv_files(s3_bucket, s3_folder_path)

3. 批量导入CSV到MySQL

提供两种方案,按需选择:

方案一:Pandas写入(适合小文件,代码简洁)

# 建立MySQL连接
mysql_conn = pymysql.connect(
    host=mysql_host,
    user=mysql_user,
    password=mysql_password,
    database=mysql_db,
    autocommit=True
)

for file_key in target_csv_files:
    # 从S3读取CSV到内存,避免本地存储
    s3_obj = s3_client.get_object(Bucket=s3_bucket, Key=file_key)
    csv_content = s3_obj['Body'].read().decode('utf-8')
    df = pd.read_csv(StringIO(csv_content))
    
    # 从文件名提取表名(可根据需求自定义规则)
    table_name = file_key.split('/')[-1].replace('.csv', '')
    
    # 写入MySQL,不存在则创建表
    df.to_sql(
        name=table_name,
        con=mysql_conn,
        if_exists='replace',  # 可选值:append/replace/fail
        index=False
    )
    print(f"完成导入:{file_key} → {table_name}")

mysql_conn.close()

方案二:MySQL LOAD DATA(适合大文件,性能更优)

import os
import tempfile

# 必须开启local_infile才能使用LOAD DATA LOCAL
mysql_conn = pymysql.connect(
    host=mysql_host,
    user=mysql_user,
    password=mysql_password,
    database=mysql_db,
    local_infile=True,
    autocommit=True
)
cursor = mysql_conn.cursor()

for file_key in target_csv_files:
    table_name = file_key.split('/')[-1].replace('.csv', '')
    
    # 下载CSV到临时文件,避免占用本地长期存储
    with tempfile.NamedTemporaryFile(mode='w+b', suffix='.csv', delete=False) as temp_file:
        s3_client.download_fileobj(s3_bucket, file_key, temp_file)
        temp_file_path = temp_file.name
    
    try:
        # 自动创建表(简单字段类型示例,复杂类型需手动调整)
        s3_obj = s3_client.get_object(Bucket=s3_bucket, Key=file_key)
        header_line = s3_obj['Body'].readline().decode('utf-8').strip().split(',')
        create_table_sql = f"CREATE TABLE IF NOT EXISTS {table_name} ({', '.join([f'{col} VARCHAR(255)' for col in header_line])})"
        cursor.execute(create_table_sql)
        
        # 执行LOAD DATA导入
        load_sql = f"""
        LOAD DATA LOCAL INFILE '{temp_file_path}'
        INTO TABLE {table_name}
        FIELDS TERMINATED BY ','
        ENCLOSED BY '"'
        LINES TERMINATED BY '\n'
        IGNORE 1 ROWS;  # CSV含表头则添加此行
        """
        cursor.execute(load_sql)
        print(f"完成大文件导入:{file_key} → {table_name}")
    except Exception as e:
        print(f"导入失败 {file_key}:{str(e)}")
    finally:
        # 删除临时文件
        os.unlink(temp_file_path)

cursor.close()
mysql_conn.close()

常见失败原因排查

  • S3权限缺失:检查IAM角色是否配置了s3:GetObject和s3:ListBucket权限
  • MySQL连接异常:确认主机可访问、账号密码正确,使用LOAD DATA时需开启local_infile参数
  • CSV格式不统一:检查编码是否为UTF-8、分隔符/引号规则是否一致、表头与表字段是否匹配
  • 内存溢出:大文件避免用Pandas全量加载,优先选择LOAD DATA方案

内容的提问来源于stack exchange,提问作者beginofwork

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:37:34