You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

批量导入TXT到PostgreSQL的API运行数文件后崩溃求助

问题分析与修复方案

首先看你的报错和代码,核心问题不是真的手动触发了KeyboardInterrupt,而是服务阻塞+数据库连接/资源耗尽导致系统主动中断了请求,同时服务器超时返回空响应。下面一步步拆解问题和修复:

核心问题定位

  1. 阻塞式sleep拖垮服务:代码里的sleep(10)和sleep(5)完全没必要,你的API基于Tornado/Bottle这类同步框架,sleep会直接阻塞整个服务线程。处理到第4个文件时,累计的等待时间超过了服务器的超时阈值,服务器直接中断了请求,就出现了KeyboardInterrupt和curl: (52) Empty reply from server。
  2. 数据库连接管理不当:单个连接持续处理多个插入操作,容易出现事务堆积、连接超时或资源泄漏,到一定次数后就会触发崩溃。
  3. 无批量插入控制: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:48:53