基于Excel表条件循环导入SQL数据的参数错误排查
问题排查与解决
原始数据说明
combined表(Excel导入的DataFrame)
| author | shift_start | shift_end |
|---|---|---|
| Brown | 2022-11-01 11:00:00 | 2022-11-01 15:00:00 |
| Crandell | 2022-11-01 11:00:00 | 2022-11-01 15:00:00 |
| Garzone | 2022-11-01 11:00:00 | 2022-11-01 15:00:00 |
| Molinari | 2022-11-01 11:00:00 | 2022-11-01 15:00:00 |
| Brown | 2022-11-01 15:00:00 | 2022-11-01 19:00:00 |
| Crandell | 2022-11-01 15:00:00 | 2022-11-01 19:00:00 |
| Garzone | 2022-11-01 15:00:00 | 2022-11-01 19:00:00 |
| Molinari | 2022-11-01 15:00:00 | 2022-11-01 19:00:00 |
| Brown | 2022-11-01 19:00:00 | 2022-11-01 23:00:00 |
NOTES表(SQL数据库表)
| ID | RESULT_DT_TM | Author |
|---|---|---|
| 1 | 2022-11-01 12:34:00 | Brown |
| 2 | 2022-11-01 12:14:00 | White |
| 3 | 2022-11-01 07:38:00 | Garzone |
| 4 | 2022-11-01 14:22:00 | Molinari |
预期导入结果(T_Assessment表)
| ID | RESULT_DT_TM | Author |
|---|---|---|
| 1 | 2022-11-01 12:34:00 | Brown |
| 4 | 2022-11-01 14:22:00 | Molinari |
错误原因分析
代码核心问题有两点:
- 循环逻辑错误:
for record in combined遍历的是DataFrame的列名而非每一行;combined['shift_start']取的是整个列的Series对象,不是单一行的时间值 - 参数传递错误:
params=[start_date,end_date,author]传入的是三个Series,数据库将其识别为表值参数(TVP),但Series不符合数据库要求的序列对象格式,因此抛出"A TVP's rows must be Sequence objects."错误
解决方案
方案1:逐行遍历查询(适合小数据量)
修正循环逻辑,遍历DataFrame的每一行,每次传入单一行的参数值,最后合并结果:
import pandas as pd # 初始化空DataFrame存储最终结果 T_Assessment_v1 = pd.DataFrame() # 遍历combined的每一行数据 for _, row in combined.iterrows(): start_date = row['shift_start'] end_date = row['shift_end'] author = row['author'] # 注意SQL字段名要与数据库实际表匹配 sql = """ SELECT * FROM ED_NOTES_MASTER WHERE RESULT_DT_TM >= ? AND RESULT_DT_TM < ? AND RESULT_TITLE_TEXT = 'SZ ED Triage/Assessment' AND author = ? """ # 执行单次查询并合并结果 temp_df = pd.read_sql(sql, conn, params=[start_date, end_date, author]) T_Assessment_v1 = pd.concat([T_Assessment_v1, temp_df], ignore_index=True) # 去重,避免同一记录被多个班次区间匹配 T_Assessment_v1 = T_Assessment_v1.drop_duplicates(subset='ID')
方案2:SQL JOIN关联查询(适合大数据量,效率更高)
把combined数据导入临时表,通过关联查询直接筛选符合条件的数据,避免多次数据库交互:
import pandas as pd from sqlalchemy import create_engine # 用SQLAlchemy引擎连接数据库(替换为你的连接字符串) engine = create_engine("你的数据库连接字符串") # 将combined导入临时表 combined.to_sql('temp_combined', engine, if_exists='replace', index=False) # 执行关联查询 sql = """ SELECT DISTINCT n.* FROM ED_NOTES_MASTER n JOIN temp_combined c ON n.author = c.author AND n.RESULT_DT_TM >= c.shift_start AND n.RESULT_DT_TM < c.shift_end WHERE n.RESULT_TITLE_TEXT = 'SZ ED Triage/Assessment' """ T_Assessment_v1 = pd.read_sql(sql, engine) # 可选:删除临时表 with engine.connect() as conn: conn.execute("DROP TABLE temp_combined")
关键注意事项
- 确保SQL语句中的字段名与数据库实际表完全匹配(比如原错误中
DT_TM实际应为RESULT_DT_TM) - 时间字段格式需统一,避免时区或格式不兼容问题
- 大数据量场景优先选择方案2,减少数据库交互次数,提升执行效率
内容的提问来源于stack exchange,提问作者Raven
相关产品推荐
相关产品推荐

