以下代码实现了用 Pandas 读取 Excel,并按要求生成分批的 SQL WHERE 条件:
python
import pandas as pd
import numpy as np
from math import ceil
def build_condition(field, value):
"""根据字段值和类型构造单个条件片段"""
if pd.isna(value):
return f"{field} IS NULL"
# 处理日期时间类型
if isinstance(value, (pd.Timestamp, np.datetime64)):
# 转换为 SQL 标准格式的字符串
val_str = pd.to_datetime(value).strftime('%Y-%m-%d %H:%M:%S')
return f"{field} = '{val_str}'"
# 处理字符串类型
if isinstance(value, str):
# 转义单引号:替换为一个单引号为两个单引号
escaped = value.replace("'", "''")
return f"{field} = '{escaped}'"
# 处理数值类型(int, float, np.number)
if isinstance(value, (int, float, np.number)):
return f"{field} = {value}"
# 其他情况(例如布尔值等)作为字符串处理
val_str = str(value).replace("'", "''")
return f"{field} = '{val_str}'"
def generate_where_batches(df, batch_size=100):
"""
将 DataFrame 的每一行转换为 AND 连接的条件组,
每 batch_size 个组用 OR 连接为一批,返回批次的列表
"""
fields = df.columns.tolist()
row_conditions = []
for _, row in df.iterrows():
# 构建单个行的条件列表
conds = []
for field in fields:
cond = build_condition(field, row[field])
conds.append(cond)
# 用 AND 连接,并加上括号形成一个条件组
group = "(" + " AND ".join(conds) + ")"
row_conditions.append(group)
# 分批,每 batch_size 个组用 OR 连接
batches = []
for i in range(0, len(row_conditions), batch_size):
batch_groups = row_conditions[i:i+batch_size]
batch_str = " OR ".join(batch_groups)
batches.append(batch_str)
return batches
# ------------------- 使用示例 -------------------
if __name__ == "__main__":
# 请替换为实际的 Excel 文件路径
excel_file = "data.xlsx"
# 读取 Excel(默认读取第一个 sheet)
df = pd.read_excel(excel_file)
# 生成批次条件(每 100 条记录为一批)
batches = generate_where_batches(df, batch_size=100)
# 打印输出每一批
for idx, batch in enumerate(batches, start=1):
print(f"--- 第 {idx} 批 (WHERE 条件部分) ---")
print(batch)
print() # 空行分隔
主要特性说明
- 空值处理 :
pd.isna()检测缺失值,生成字段 IS NULL。 - 字符串与日期 :字符串值用单引号包裹,内部单引号替换为两个单引号;日期时间格式化为
'YYYY-MM-DD HH:MM:SS'并加单引号。 - 数字:整数、浮点数直接拼接,不加引号。
- 分批输出 :每 100 个行条件组用
OR连接为一批,打印时按批次输出。
使用前准备
-
安装依赖(若未安装):
bashpip install pandas openpyxl -
将脚本中的
excel_file路径改为你的 Excel 文件实际路径。 -
运行脚本即可看到控制台输出的分批 WHERE 条件。
示例输出片段
假设 Excel 有三行数据:
| name | age | created_at |
|---|---|---|
| John | 30 | 2023-01-01 10:00:00 |
| NULL | 25 | NULL |
| O'Brien | 40 | 2023-02-01 12:30:00 |
生成的第一批(此处只有 3 条,仍按 100 条分一批):
--- 第 1 批 (WHERE 条件部分) ---
(name = 'John' AND age = 30 AND created_at = '2023-01-01 10:00:00') OR (name IS NULL AND age = 25 AND created_at IS NULL) OR (name = 'O''Brien' AND age = 40 AND created_at = '2023-02-01 12:30:00')
注意 O'Brien 被正确转义为 'O''Brien'。