我正在尝试插入此数据
[{
"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多对多插入数据)和提交顺序,但没有帮助
通过检查官员是否已经在新的
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()