对 SQLAlchemy 中的 UniqueKeyViolation 做出反应
我在 SQLAlchemy 中有 2 个表(使用 declerative_base()
),它们通过单独的表关系连接起来
# no comment on the wired naming....
site_word = Table('word_site', Base.metadata,
Column('site_id', Integer, ForeignKey('sites.site_id'), nullable = False, primary_key = True),
Column('word_id', Integer, ForeignKey('site_words.word_id'), nullable = False, primary_key = True))
单词映射
class Word(Base):
# snip
word = Column('word', Text, nullable = False, unique = True)
sites = relationship('Site', secondary = site_word, back_populates = 'words')
站点映射
class Site(Base):
# snip
words = relationship('Word', secondary = site_word, back_populates = 'sites')
插入工作如预期,插入已经存在的单词当然会失败,因为 唯一
在 Word.word
中。
我尝试使用 before_insert 事件来检查该项目是否已存在。
event.listen(Word, 'before_insert', some_event)
我可以获得信息来按预期唯一识别单词,但我不知道如何向连接表 (site_word
) 添加新值。
我可以为数据库编写触发器或过程,但不想将太多逻辑移入数据库(不知道这是否可行,因为此时不知道 Site
时间)。我可以删除 word
列的约束,但我仍然无法弄清楚如何访问信息(连接的另一端)以在连接表中创建条目,但不能在Word
表。
我正在寻找一种方法仅在 site_word
和 Site
表中创建条目。
更新 1:
我可以将事件附加到 Site
,但我看不到获取要插入的站点信息的可能性。是否可以保存站点并随后创建连接关系?
I have 2 Tables in SQLAlchemy (using declerative_base()
) that are joined via a seperate Table relationship
# no comment on the wired naming....
site_word = Table('word_site', Base.metadata,
Column('site_id', Integer, ForeignKey('sites.site_id'), nullable = False, primary_key = True),
Column('word_id', Integer, ForeignKey('site_words.word_id'), nullable = False, primary_key = True))
Word mapping
class Word(Base):
# snip
word = Column('word', Text, nullable = False, unique = True)
sites = relationship('Site', secondary = site_word, back_populates = 'words')
Site mapping
class Site(Base):
# snip
words = relationship('Word', secondary = site_word, back_populates = 'sites')
Inserting works like expected, inserting of already existing words fails of course due to unique
in Word.word
.
I tried using a before_insert event to check if the item already exists.
event.listen(Word, 'before_insert', some_event)
I can get the information to identify the word uniquly as expected but I don't know how to add a new value to the join table (site_word
).
I could write a trigger or procedure for the database but don't want to move too much logic into the database (don't know if this would be possible since the Site
wouldn't be known at that time). I could remove the constraint for the word
-column but I still can't figure out how to access the information (the other end of the join) to create an entry in the join table, but not in the Word
table.
I am looking for a way to create a entry in the site_word
and Site
table only.
update 1:
I could attach the event to the Site
but I don't see a possibility to get the information of the to-be-inserted Site. Is there a possibility to save the Site and create the join-relation afterwards?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果没有如何使用对象的示例,就很难看出问题。我认为您正在尝试执行以下操作:
如果“someword”已经存在,这当然会引发
IntegrityError
。为了解决这个问题,您需要先在数据库中查询该单词,然后再将其添加到网站:如果这完全不合理,那么您必须更详细地描述您的问题。
It is difficult to see the problem without an example of how you are working with your objects. I take it you are trying to do something like this:
This will of course raise an
IntegrityError
if 'someword' already exists. To get around this, you need to first query the database for the word before adding it to the site:If this is completely off base, then you'll have to describe your problem in greater detail.
我设法做到了。 Mark Gemmill 的答案让我朝着正确的方向思考。
我需要听 AttributeEvent 而不是 MapperEvent。
然后我可以做类似的事情:
这要么从表中返回现有的单词,要么只是返回需要持久化的映射对象。
I managed to do it. Mark Gemmill's answer got me thinking in the right direction.
I need to listen to an AttributeEvent instead of an MapperEvent.
Then I can do something like:
This either returns the existing word from the table or simply returns the mapped object that needs to be persisted.