使用Python watchdog监听文件并写入SQL Server的代码异常问题
问题原因
你的SQL写入逻辑永远不会执行,核心原因是代码执行流被阻塞:
- 启动监听后
while(True): time.sleep(1)是无限循环,只要不手动按Ctrl+C触发KeyboardInterrupt,程序会一直卡在这个循环,根本走不到后面创建数据库连接、遍历文件的代码。 - 就算手动中断程序,原有代码还有多处语法和逻辑错误:
- 导入语句格式错误,
time、Observer、FileSystemEventHandler的导入写串了 - 没有导入
create_engine方法,也没有给pandas设置pd别名,运行会直接报名称错误 - 遍历目录用的是
os.listdir('.'),扫的是程序运行的当前工作目录,不是你配置的监听路径 - 用
split('.')切分文件名后缀,遇到文件名带多个点的情况会报错,应该用os.path.splitext处理 - 写入逻辑和监听事件完全解绑,就算监听到文件夹里新增了xlsx文件,也不会触发写入操作。
- 导入语句格式错误,
修正后完整代码
import pandas as pd import os from sqlalchemy import create_engine import time from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler # 提前替换为自己的配置 MONITOR_PATH = "替换为要监听的文件夹绝对路径" DB_CONN_STR = "替换为SQL Server连接串,例:mssql+pymssql://用户名:密码@数据库地址:端口/库名" class EventHandler(FileSystemEventHandler): def __init__(self, engine): self.engine = engine super().__init__() def write_excel_to_sql(self, file_path): # 过滤非xlsx文件、Excel生成的临时锁文件 if not file_path.endswith('.xlsx') or os.path.basename(file_path).startswith('~$'): return # 等待文件写入完成,避免文件被占用读取失败 time.sleep(1) try: file_basename = os.path.splitext(os.path.basename(file_path))[0] df = pd.read_excel(file_path) df.to_sql(file_basename, con=self.engine, if_exists='replace', index=False) print(f"文件 {file_path} 写入完成,对应表名:{file_basename}") except Exception as e: print(f"写入文件 {file_path} 失败:{str(e)}") def on_created(self, event): # 新建文件时触发写入 if not event.is_directory: self.write_excel_to_sql(event.src_path) def on_moved(self, event): # 处理文件重命名为xlsx的场景 if not event.is_directory: self.write_excel_to_sql(event.dest_path) if __name__ == "__main__": # 初始化数据库连接 engine = create_engine(DB_CONN_STR) # 启动时先扫描目录内已有的xlsx文件完成初始化写入 handler = EventHandler(engine) for file in os.listdir(MONITOR_PATH): full_path = os.path.join(MONITOR_PATH, file) if os.path.isfile(full_path): handler.write_excel_to_sql(full_path) # 启动持续监听 observer = Observer() observer.schedule(handler, MONITOR_PATH, recursive=True) print("监听已启动,符合要求的xlsx文件将自动写入SQL Server") observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join()
运行注意事项
- 运行前先安装依赖:
pip install pandas openpyxl sqlalchemy pymssql watchdog,如果使用Windows身份验证连接SQL Server,也可以替换pymssql为pyodbc,对应修改连接串格式即可。 - 代码绑定了文件新建、重命名两个事件,覆盖了文件上传、重命名修改后缀的常见场景,监听到符合要求的文件会自动执行写入,不需要中断程序触发。
- 写入时加了
index=False参数,避免把pandas默认的行索引写入数据库表。
内容的提问来源于stack exchange,提问作者Awais Farooqui
相关产品推荐
相关产品推荐

