如何将中等规模CSV导入Heroku的JawsDB MySQL数据库?
可行的CSV导入方案(针对JawsDB Leopard共享库)
方案1:分批次批量INSERT+延迟控制
共享MySQL库的max_questions限制是短时间内的查询次数阈值,核心思路是减少单位时间内的查询量,同时用批量插入降低单批次的查询数。
步骤:
- 将大CSV拆分为包含500-1000条记录的小文件(可根据实际限制调整批次大小),保留表头。
- 编写脚本读取每个小文件,生成单条INSERT语句包含多条记录的SQL(比如
INSERT INTO table (col1, col2) VALUES (val1,val2), (val3,val4), ...),大幅减少查询次数。 - 每执行完一个批次后,暂停2-5秒,避免触发频率限制。
Python示例脚本:
import pandas as pd import time import mysql.connector # 替换为你的JawsDB连接信息 db_config = { 'user': '你的数据库用户名', 'password': '你的数据库密码', 'host': '你的JawsDB主机地址', 'database': '你的数据库名' } # 读取原始CSV df = pd.read_csv('你的大CSV文件.csv') batch_size = 800 # 可根据测试结果调整 for batch_idx in range(0, len(df), batch_size): batch_data = df.iloc[batch_idx:batch_idx+batch_size] # 构造批量INSERT语句 cols = ', '.join(batch_data.columns) value_rows = [] for _, row in batch_data.iterrows(): # 处理字符串转义和空值 formatted_vals = [] for val in row.values: if pd.isna(val): formatted_vals.append('NULL') elif isinstance(val, str): formatted_vals.append(f"'{val.replace('\\', '\\\\').replace('\'', '\\\'')}'") else: formatted_vals.append(str(val)) value_rows.append(f"({', '.join(formatted_vals)})") insert_sql = f"INSERT INTO 你的目标表名 ({cols}) VALUES {', '.join(value_rows)};" # 执行插入 conn = mysql.connector.connect(**db_config) cursor = conn.cursor() try: cursor.execute(insert_sql) conn.commit() print(f"已完成第 {batch_idx//batch_size + 1} 批次插入") except Exception as e: print(f"第 {batch_idx//batch_size + 1} 批次插入失败: {str(e)}") conn.rollback() finally: cursor.close() conn.close() # 延迟避免触发频率限制 time.sleep(3)
方案2:Shell分批次+管道式LOAD DATA
如果习惯用命令行工具,可通过拆分CSV+管道传递数据给MySQL客户端,绕开LOCAL权限限制,同时控制批次和延迟:
步骤:
- 拆分CSV文件,单独提取表头,将数据部分拆分为小批次文件。
- 对每个小批次文件,结合表头通过管道传递给
LOAD DATA INFILE(读取标准输入而非本地文件)。 - 每批次执行后添加延迟。
Shell命令示例:
# 1. 提取CSV表头 head -n 1 large_data.csv > header.csv # 2. 拆分数据部分为每个1000行的小文件(跳过表头) tail -n +2 large_data.csv | split -l 1000 - split_batch_ # 3. 逐个导入小批次 for batch_file in split_batch_*; do # 拼接表头和批次数据,通过管道传给MySQL cat header.csv "$batch_file" | mysql -h 你的JawsDB主机地址 -u 你的用户名 -p你的密码 你的数据库名 -e " LOAD DATA INFILE '/dev/stdin' INTO TABLE 你的目标表名 FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\n' IGNORE 1 ROWS; # 跳过表头行 " # 延迟3秒 sleep 3 done # 清理临时文件 rm header.csv split_batch_*
关键注意事项
- 先测试小批次(比如100条),调整批次大小和延迟时间,确保不会触发
max_questions限制。 - 确认目标表结构与CSV的字段顺序、数据类型完全匹配,避免插入失败。
- 批量INSERT时注意单条SQL语句的长度不要超过MySQL的
max_allowed_packet限制,若出现相关错误,缩小批次大小。
内容的提问来源于stack exchange,提问作者Daelso
相关产品推荐
相关产品推荐

