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

在Flask中用SQLAlchemy批量添加列表数据至数据库时重复提交问题

解决Flask-SQLAlchemy重复提交数据的问题

问题背景

我有如下数据列表:

experience =[{}, {}, {}] # 包含3个对象的列表
project = [{}...]

已创建对应的Flask-SQLAlchemy模型,尝试通过以下代码将数据添加至数据库:

# 在app_context()函数内添加数据到数据库
with app.app_context():
    # 提交更改

    # 向数据库添加项目数据
    for project in projectData:
        project_entry = Project(
            projectName=project["projectName"],
            projectDescription=project["projectDescription"],
            projectUrl=project["projectUrl"],
        )
        db.session.add(project_entry)

    # 向数据库添加工作经历数据
    for data in experience_data:
        experience_entry = Experience(
            companyName=data["companyName"],
            companyDescription=data["companyDescription"],
            companyUrl=data["companyUrl"],
            companyRole=data["companyRole"],
            companyDuration=data["companyDuration"],
            companyLocation=data["companyLocation"],
            companyResponsibilities=data["companyResponsibilities"],
            projects=data["projects"]
        )
        db.session.add(experience_entry)

    # 添加完所有数据后提交更改
    db.session.commit()

遇到的问题:每次加载时数据都会重复提交,预期仅3行数据但实际已有54行;若移出app.app_context()则会触发应用上下文错误,如何实现仅一次性将数据存储至数据库?


解决方法

1. 插入前检查数据是否已存在

在添加每条数据前,通过唯一标识字段(如项目名、公司名+职位组合)查询数据库,仅当记录不存在时才插入:

with app.app_context():
    # 处理项目数据
    for project in projectData:
        existing_project = Project.query.filter_by(projectName=project["projectName"]).first()
        if not existing_project:
            project_entry = Project(
                projectName=project["projectName"],
                projectDescription=project["projectDescription"],
                projectUrl=project["projectUrl"],
            )
            db.session.add(project_entry)

    # 处理工作经历数据
    for data in experience_data:
        # 以公司名+职位作为唯一判断条件,可根据实际业务调整
        existing_experience = Experience.query.filter_by(
            companyName=data["companyName"],
            companyRole=data["companyRole"]
        ).first()
        if not existing_experience:
            experience_entry = Experience(
                companyName=data["companyName"],
                companyDescription=data["companyDescription"],
                companyUrl=data["companyUrl"],
                companyRole=data["companyRole"],
                companyDuration=data["companyDuration"],
                companyLocation=data["companyLocation"],
                companyResponsibilities=data["companyResponsibilities"],
                projects=data["projects"]
            )
            db.session.add(experience_entry)

    db.session.commit()

2. 编写独立初始化脚本,仅手动执行一次

将数据插入逻辑从应用启动代码中剥离,做成单独的初始化脚本,只运行一次:

创建init_db.py文件:

# 导入你的应用、数据库模型和数据
from your_app import app, db, Project, Experience
from your_data_source import projectData, experience_data

with app.app_context():
    # 先创建数据库表(如果还未创建)
    db.create_all()
    
    # 插入项目数据(带存在性检查)
    for project in projectData:
        if not Project.query.filter_by(projectName=project["projectName"]).first():
            project_entry = Project(**project)
            db.session.add(project_entry)
    
    # 插入工作经历数据(带存在性检查)
    for data in experience_data:
        if not Experience.query.filter_by(companyName=data["companyName"], companyRole=data["companyRole"]).first():
            experience_entry = Experience(**data)
            db.session.add(experience_entry)
    
    db.session.commit()
    print("数据初始化完成,已成功插入非重复数据")

在终端执行一次该脚本:

python init_db.py

之后启动应用时,这段插入逻辑不会重复执行,也就不会产生重复数据。

3. 给数据库添加唯一约束

在模型类中为易重复的字段添加唯一约束(单个字段或联合字段),从数据库层面阻止重复插入:

class Project(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    projectName = db.Column(db.String(100), unique=True, nullable=False)  # 项目名唯一
    projectDescription = db.Column(db.Text)
    projectUrl = db.Column(db.String(200))

class Experience(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    companyName = db.Column(db.String(100), nullable=False)
    companyRole = db.Column(db.String(100), nullable=False)
    # 添加公司名+职位的联合唯一约束
    __table_args__ = (
        db.UniqueConstraint('companyName', 'companyRole', name='_company_role_unique'),
    )
    # 其他字段...

插入时捕获数据库的完整性错误,跳过重复数据:

from sqlalchemy.exc import IntegrityError

with app.app_context():
    try:
        # 批量添加项目数据
        for project in projectData:
            project_entry = Project(**project)
            db.session.add(project_entry)
        
        # 批量添加工作经历数据
        for data in experience_data:
            experience_entry = Experience(**data)
            db.session.add(experience_entry)
        
        db.session.commit()
    except IntegrityError:
        db.session.rollback()
        print("检测到重复数据,已回滚操作,未插入重复记录")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 15:45:07