sqlalchemy 中的多对多。如果标签已存在,怎么防止 SQLAlchemy 重复插入标签

2021-08-24 18:40:49 +08:00
 holinhot

几乎和这个一样。 https://stackoverflow.com/questions/13149829/many-to-many-in-sqlalchemy-preventing-sqlalchemy-from-inserting-into-a-table-if

看了下答案,一会说是用 upset 。还有说用 unique object (没看懂)

我建了三个表。文章表,标签表( name 唯一约束),标签文章关系表双主键。这起起来很标准啊,难道不给标签表,name 做唯一约束,这会存很多重复的 Tag 记录,完全没必要。

还是要自己先查一遍标签是否存在,如果存在怎么调用 SQLAlchemy 来只插入关系记录,而不插入标签。

def create(db: Session, data: core.schemas.article.Create):
    data.source_images = json.dumps(data.source_images)
    data_dict = data.dict(exclude_unset=True)
    data_dict.pop('tag')
    db_data = schemas.article.Article(**data_dict)
    if data.tag:
        for item in data.tag:
            tag = core.model.article.Article(name=item)
            db_data.article.append(tag)
            
    db.add(db_data)
    db.commit()
    db.refresh(db_data)
    return db_data

这样搞了提交文章时如果标签在标签表已存了 SQLAlchemy 还是会执行插入,但受唯一条件约束而执行失败。

sqlalchemy.exc.IntegrityError: (psycopg2.errors.UniqueViolation) duplicate key value violates unique constraint "ix_name"
DETAIL:  Key (name)=(string) already exists.
828 次点击
所在节点    问与答
1 条回复
holinhot
2021-08-24 19:05:49 +08:00
好像这样可以了
if data.actress:
for item in data.actress:
db_tag = db.query(core.model.actress.Actress).filter(core.model.actress.Actress.name == item).first()
if not db_tag:
tag = core.model.actress.Actress(name=item)
db_data.actress.append(tag)
else:
db_data.actress.append(db_tag)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/797774

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX