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

生成器迭代未触发StopIteration,数据入库收尾失败求助

问题描述

将超百万条数据的生成器内容导入SQL数据库,采用每10000条存入Pandas DataFrame后通过to_sql提交的方案。填满批次时运行正常,但最后一批处理完后,StopIteration从未触发,程序无响应。调试发现第1384471条数据已处理,再次调用next时既无新数据也不抛出异常,程序停滞。改用for循环后,循环后的收尾代码也未执行。

相关核心代码如下:

import ijson
import pandas as pd
import sqlalchemy as sa

def connect_to_database():
    engine = sa.create_engine(f"postgresql+psycopg2://{USER}:{PWD}@{SERVERNAME}:{PORT}/{DB}")
    return engine

engine = connect_to_database()

def create_content(objects, table_name):
    '''从JSON文件的对象列表中提取内容'''
    item_lst = []
    item_count = 0

    while True:
        try:
            item = next(objects)
            value_conversion(item)
            item_lst.append(item)
            
            if len(item_lst) == 10000:
                item_count += len(item_lst)
                submit_sql(table_name, item_lst)
                item_lst.clear()

        except StopIteration:
            if len(item_lst) > 0:
                item_count += len(item_lst)
                submit_sql(table_name, item_lst)
                item_lst.clear()
                print(item_count)
            break               
        except Exception as e:
            print(e)

def submit_sql(engine, table_name, items):
    '''提交DataFrame内容到SQL数据库'''
    engine = connect_to_database()
    temp_df = pd.DataFrame(items)
    temp_df.to_sql(table_name, engine, if_exists='append', index=False)
    engine.dispose()

with open("C:/Path/To/Json/file.json", "r", encoding="utf-8") as json_file:
    s_objects = ijson.items(json_file, 'ObjectList.item')
    create_content(s_objects, 'tablename')

尝试的for循环版本:

try:
    for item in objects:
        value_conversion(item)
        item_lst.append(item)
        
        if len(item_lst) == 10000:
            item_count += len(item_lst)
            submit_sql(table_name, item_lst)
            item_lst.clear()
            print(item_count)

    if len(item_lst) > 0:
        item_count += len(item_lst)
        submit_sql(table_name, item_lst)
        item_lst.clear()
        print(item_count)

except Exception as e:
    print(e)
问题排查与原因分析
  1. ijson生成器未正常终止
    ijson采用流式解析JSON,若JSON文件存在格式问题(如末尾多余逗号、未闭合的括号/引号,或隐藏的无效字符),解析器会卡在最后一段数据之后,既不返回新数据也不抛出StopIteration,导致程序无限等待。

  2. 数据库连接的冗余操作
    submit_sql函数每次提交都重新创建数据库引擎并立即销毁,频繁的连接建立/销毁会消耗大量资源,不仅降低效率,还可能引发连接池异常,拖慢甚至阻塞最后批次的处理流程。此外,函数定义的engine参数未被使用,属于冗余代码。

  3. 循环计数逻辑的潜在问题
    原while循环中item_count仅在批次满10000时累加,若生成器因解析问题阻塞,StopIteration分支的收尾代码根本无法执行;for循环版本的收尾代码同样因生成器未终止而无法触发。

修复方案

1. 修复JSON解析问题

  • 先检查JSON文件完整性:用本地工具(如python -m json.tool your_file.json)验证文件格式,修复末尾无效字符、未闭合结构等问题。
  • 改用itertools.islice分批处理生成器,更可靠地检测迭代终止。

2. 优化数据库连接逻辑

复用数据库引擎,避免频繁创建/销毁连接:

def submit_sql(engine, table_name, items):
    '''提交items到SQL数据库'''
    temp_df = pd.DataFrame(items)
    temp_df.to_sql(table_name, engine, if_exists='append', index=False)

3. 重构批次处理逻辑

使用itertools.islice实现更稳定的分批迭代,确保能正确检测生成器终止:

from itertools import islice

def create_content(objects, table_name, engine):
    item_count = 0
    while True:
        # 每次从生成器中取10000条数据
        batch = list(islice(objects, 10000))
        if not batch:
            # 批次为空,说明迭代完全结束
            break
        # 处理批次内的每个item
        for item in batch:
            value_conversion(item)
        # 提交到数据库
        submit_sql(engine, table_name, batch)
        item_count += len(batch)
        print(f"已处理 {item_count} 条数据")

4. 完善调用流程

确保数据库引擎在处理完成后正确销毁,同时捕获可能的解析异常:

with open("C:/Path/To/Json/file.json", "r", encoding="utf-8") as json_file:
    s_objects = ijson.items(json_file, 'ObjectList.item')
    engine = connect_to_database()
    try:
        create_content(s_objects, 'tablename', engine)
    except Exception as e:
        print(f"处理过程中出现错误: {str(e)}")
    finally:
        # 确保引擎最终被销毁
        engine.dispose()

额外建议

  • 在value_conversion函数中添加异常捕获,避免单个数据项的转换错误导致整个流程阻塞:
    def value_conversion(item):
        try:
            # 原转换逻辑
            pass
        except Exception as e:
            print(f"转换数据项失败: {str(e)}, 数据项: {item}")
            # 可选:跳过错误项或记录日志
    

内容的提问来源于stack exchange,提问作者TomGeo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 04:27:13