You need to enable JavaScript to run this app. Flask-Migrate迁移中新建engine执行批量插入挂起如何解决
优惠活动
大模型
产品
解决方案
定价
更多

Flask-Migrate迁移中新建engine执行批量插入挂起如何解决

问题原因

你的实现存在两个核心问题直接导致进程挂起:

  1. 事务锁冲突:Alembic运行upgrade函数时默认已经开启了一个事务并持有目标表的锁,你额外创建的新引擎会生成独立的数据库连接,这个新连接需要等待原有Alembic事务释放锁才能执行插入操作,最终形成死锁导致挂起。
  2. 批量优化未生效配置缺失:SQLAlchemy 1.3.x版本的bulk_save_objects默认会开启return_defaults参数获取插入记录的主键,该参数会打断批量executemany优化,变成单条插入反而降低效率。

修复方案

不需要额外创建新引擎,直接复用Alembic现有连接并补充批量配置即可,修改后的代码如下:

from alembic import op
from sqlalchemy.orm.session import Session

def upgrade():
    list_of_objects_to_insert = get_and_process_objects_from_csv_file()
    # 直接获取现有连接的引擎,修改executemany配置
    engine = op.get_bind().engine
    engine.update_execution_options(executemany_mode='values_plus_batch')
    session = Session(bind=engine)
    
    # 分批插入避免单次请求过大,每批1000条可根据实际调整
    batch_size = 1000
    for i in range(0, len(list_of_objects_to_insert), batch_size):
        batch = list_of_objects_to_insert[i:i+batch_size]
        # 关闭return_defaults避免打断批量插入
        session.bulk_save_objects(batch, return_defaults=False)
        session.commit()
    session.close()
    print('Inserted all records from bulk list')

额外优化建议
  • 可根据实际测试调整batch_size数值,通常PostgreSQL单批插入500-2000条性能最优
  • 如果需要进一步提升速度,可直接用SQLAlchemy Core的insert语句配合values_list批量插入,性能比ORM的bulk_save_objects高15%-30%
  • 若调整后仍触发CircleCI超时,可在CircleCI配置中给该迁移步骤单独设置更长的no_output_timeout参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 22:15:03