批量导入TXT到PostgreSQL的API运行数文件后崩溃求助
问题分析与修复方案
首先看你的报错和代码,核心问题不是真的手动触发了KeyboardInterrupt,而是服务阻塞+数据库连接/资源耗尽导致系统主动中断了请求,同时服务器超时返回空响应。下面一步步拆解问题和修复:
核心问题定位
- 阻塞式sleep拖垮服务:代码里的
sleep(10)和sleep(5)完全没必要,你的API基于Tornado/Bottle这类同步框架,sleep会直接阻塞整个服务线程。处理到第4个文件时,累计的等待时间超过了服务器的超时阈值,服务器直接中断了请求,就出现了KeyboardInterrupt和curl: (52) Empty reply from server。 - 数据库连接管理不当:单个连接持续处理多个插入操作,容易出现事务堆积、连接超时或资源泄漏,到一定次数后就会触发崩溃。
- 无批量插入控制:
df.to_sql默认一次性插入所有数据,若文件较大,会瞬间占用大量内存和数据库资源,加剧崩溃概率。
具体修复步骤
1. 立刻移除无用的sleep
直接删掉这两行,别让服务平白无故阻塞:
# 删掉这两行 sleep(10) # ... sleep(5)
2. 用SQLAlchemy连接池管理数据库连接(推荐)
不要手动创建单个连接,改用SQLAlchemy的Engine来自动管理连接池,避免资源泄漏:
# 先修改你的create_connection函数,返回Engine而不是原始连接 from sqlalchemy import create_engine def create_connection(): # 替换成你的PostgreSQL连接字符串 return create_engine('postgresql://user:password@host:port/your_db')
然后在API函数里,用Engine代替手动管理的连接:
@apiR2A.route('/api/lectura', method=['POST']) def read_txt(): arch = [] arch_err = [] # 获取连接池引擎,不用手动创建/关闭连接 db_engine = create_connection() archivos = request.query.archivos for root, dirs, files in os.walk(archivos): for file in files: if not file.endswith(".txt"): continue file_path = os.path.join(root, file) try: # 读取文件 df = pd.read_csv(file_path, encoding="utf-8", sep="|", header=None) # 校验列数 if len(df.columns) != 12: print(f"WARNING: File {file_path} has wrong format\n") arch_err.append(file) continue # 设置列名 df.columns = ["1","2","3","4","5","6","7","8","9","10","11","12"] print(f'Reading: {file_path}') # 分批次插入,避免一次性占用过多资源 df.to_sql( 'FBDClientesCuentas', db_engine, if_exists='append', index=False, chunksize=1000 # 每次插1000行,可根据你的数据调整 ) print(f'{file} succesfully added to db.\n') arch.append(file) except Exception as e: # 捕获异常,单个文件出错不影响其他文件 print(f"Failed to process {file_path}: {str(e)}") arch_err.append(file) continue # 后续打印逻辑不变 if len(arch) > 0: print('Files loaded to database:') for x in arch: print(x) if len(arch_err) > 0: print('\nUnread files:') for x in arch_err: print(x)
3. 添加异常捕获,避免单个文件崩溃整个请求
上面的代码已经加了try-except,这样哪怕某个文件读取/插入出错,也只会记录错误,继续处理其他文件,不会导致整个API请求崩溃。
验证修复
做完这些修改后再测试:
- 没有sleep阻塞,API不会因为超时被服务器中断
- 连接池自动管理连接,不会出现资源耗尽的情况
- 分批次插入减少了内存和数据库资源占用
- 异常捕获保证了服务的健壮性
内容的提问来源于stack exchange,提问作者Nerdrigo
相关产品推荐
相关产品推荐

