如何使用SQLAlchemy将数据插入到多对多关系中?错误:重复的键值违反了唯一约束

问题描述 投票:0回答:1

我正在尝试插入此数据

[{
    "name": "CORVETTE",
    "officers": [{"first_name": "Alan1", "rank": "Commander"}, 
             {"first_name": "Alan2", "rank": "Soldier"}]
  },
  {
    "name": "CRUISER",
    "officers": [{"first_name": "Alan1", "rank": "Commander"}, 
             {"first_name": "Alan3", "rank": "Soldier"}]
  }
]

在 Postgres db 中进入多对多 SQLAlchemy 关系

class Officer_orm(Base):
    __tablename__ = "officer_orm"
    first_name = Column(String(255), primary_key=True)
    rank = Column(String(255), primary_key=True)

    spaceships_orm = relationship('Spaceship_orm', 
                      secondary='spaceships_officers', 
                      lazy='subquery', 
                      back_populates='officers_orm')


class Spaceship_orm(Base):
    __tablename__ = "spaceship_orm"
    name = Column(String(255), primary_key=True)

    officers_orm = relationship('Officer_orm', 
                    secondary='spaceships_officers', 
                    lazy='subquery', 
                    back_populates='spaceships_orm')            


class SpaceshipsOfficers(Base):
    __tablename__ = "spaceships_officers"

    id = Column(Integer, primary_key=True)
    o_first_name = Column(String(255))
    o_rank = Column(String(255))
    s_name = Column(String(255), ForeignKey('spaceship_orm.name'))
    __table_args__ = ((ForeignKeyConstraint(["o_first_name", "o_rank"], 
                          ["officer_orm.first_name","officer_orm.rank"])),) 

# .... fill spaceships from json
for s in json_spaceships:
    # .... fill spaceships.officers from json
    with Session(engine) as session:
        spaceship_orm = Spaceship_orm(name=s.name)
        for o in officers:
            officer_orm = Officer_orm(first_name=o.first_name, rank=o.rank)
            spaceship_orm.officers_orm.append(officer_orm)

        session.add_all([spaceship_orm])
        session.commit()                                                                                            

但是当插入第二艘宇宙飞船 CRUISER 时我收到错误

ERROR:root:(psycopg2.errors.UniqueViolation) duplicate key value violates unique constraint "officer_orm_pkey" DETAIL:  Key (first_name,rank)=(Alan1, Commander) already exists.
因为在第一次 CORVETTE 飞船插入期间 Alan1 对象已成功插入到“officer_orm”表中

您能帮我避免这个错误并正确插入所有关系吗

id o_名字 o_rank s_name
1 艾伦1 指挥官 科尔维特
2 艾伦2 士兵 科尔维特
3 艾伦1 指挥官 巡洋舰
4 艾伦3 士兵 巡洋舰

我尝试了

lazy='subquery'
Flask sqlalchemy多对多插入数据)和提交顺序,但没有帮助

python python-3.x sqlalchemy many-to-many psycopg2
1个回答
0
投票

通过检查官员是否已经在新的

session.add(officer_orm)

之前插入来修复它
with Session(engine) as session:
        spaceship_orm = Spaceship_orm(name=s.name)
        session.add(spaceship_orm)
        session.commit()

        for o in officers:
            officer_orm = Officer_orm(first_name=o.first_name, rank=o.rank)
            spaceship_orm.officers_orm.append(officer_orm)

            existed_officer = session.query(Officer_orm).filter(Officer_orm.first_name==o.first_name,
                                                                Officer_orm.rank==of.rank,
                                                                ).all()
            if len(existed_officer) == 0:
                officer_orm = Officer_orm(first_name=o.first_name, rank=o.rank)
                session.add(officer_orm)
                session.commit()
            else:
                officer_orm = existed_officer[0]
                    
            spaceship_orm.officers_orm.append(officer_orm)
            session.commit()
© www.soinside.com 2019 - 2024. All rights reserved.