如何避免在多对多关系中(sqlalchemy, python)添加重复项?
表格 authors
和 books
之间是多对多的关系。也就是说,一本书可以有很多作者,而一个作者可能写了很多书。
author_1 = Author('Dan')
session.add(author_1)
author_1.books = [Paper('Illuminati'), Book('Sacrileg')]
session.commit()
这段代码往数据库里添加了两本书和一个作者,并把它们关联起来。到目前为止,一切都很好。这两个表格中的列(authors.name
和 books.title
)都是唯一的。
现在我们来添加一个新作者,假设 Dan 在写 Illuminati 的时候得到了帮助。
author_2 = Author('Brownie')
session.add(author_2)
author_2.books = [Paper('Illuminati')]
session.commit()
结果却出现了重复错误!这是为什么呢?我是不是需要先查询一下 Paper('Illuminati')
呢?如果我有一整份书单,那我是不是得一个一个去查询?或者说,有没有什么自动的功能,像 sqlalchemy 这样可以判断某个条目是否已经存在,然后直接关联到它呢?
1 个回答
这基本上是@renatopp评论的详细版本。
这会导致重复错误!这是为什么呢?
你创建了一本新书或论文,它和数据库里已有的那本很相似。我想你给书或论文的name
设置了唯一性约束。
我需要先查询一下Paper('Illuminati')吗?
让我们看看你之前说了什么。
我们来添加一个新作者,假设Dan在写《Illuminati》的时候得到了帮助。
这个新作者帮助Dan写的正是《Illuminati》,而这本书已经在数据库里了。你那段代码的意思是“Brownie写了一本和Dan的书同名的新书”。所以就出现了两本书,这就导致了重复错误。
如果你想要“Brownie帮助Dan”,那么你得让他写同一本书。先从数据库里获取Dan的《Illuminati》,然后告诉Brownie去帮助Dan。
# illuminati = Dan's book from db
author_2.books.append(illuminati)
我在那段代码里做了修改。如果我错了请纠正我,我觉得你是想给Brownie添加一本书,而不是先把他所有的书都删掉,然后再给他一本书(author_2.books = [Paper('Illuminati')]
)。
如果我有一整本书的列表呢?我需要查询每一本书吗?
这要看情况。它们都是新书吗?还是已有的书?也许只有其中一些是新书?或者你根本不知道?
你需要检查一下,或者尝试捕获异常。