关联代理 SQLAlchemy [英] Association Proxy SQLAlchemy
问题描述
此来源详细说明如何使用关联代理创建具有 ORM 对象值的视图和对象.
This source details how to use association proxies to create views and objects with values of an ORM object.
但是,当我附加一个与数据库中现有对象匹配的值(并且所述值是唯一的或主键)时,它会创建一个冲突对象,因此我无法提交.
However, when I append an value that matches an existing object in the database (and said value is either unique or a primary key), it creates a conflicting object so I cannot commit.
所以在我的情况下,这仅用作视图,我需要使用 ORM 查询来检索要附加的对象.
So in my case is this only useful as a view, and I'll need to use ORM queries to retrieve the object to be appended.
这是我唯一的选择还是我可以使用合并(如果它是主键而不是唯一约束,我可能只能这样做),或者设置构造函数以便它使用数据库中的现有对象如果它存在而不是创建一个新对象?
Is this my only option or can I use merge (I may only be able to do this if it's a primary key and not a unique constraint), OR set up the constructor such that it will use an existing object in the database if it exists instead of creating a new object?
例如来自文档:
user.keywords.append('cheese inspector')
# Is translated by the association proxy into the operation:
user.kw.append(Keyword('cheese inspector'))
但我想被翻译成更像:(当然查询可能会失败).
But I'd like to to be translated to something more like: (of course the query could fail).
keyword = session.query(Keyword).filter(Keyword.keyword == 'cheese inspector').one()
user.kw.append(keyword)
或者理想情况下
user.kw.append(Keyword('cheese inspector'))
session.merge() # retrieves identical object from the database, or keeps new one
session.commit() # success!
我认为这甚至可能不是一个好主意,但它可能适用于某些用例:)
I suppose this may not even be a good idea, but it could be in certain use cases :)
推荐答案
您链接到的文档页面上显示的示例是 composition
类型的关系(在 OOP 术语中),因此代表拥有
关系类型而不是uses
在动词方面.因此,每个 owner
都有自己的相同(就价值而言)关键字的副本.
The example shown on the documentation page you link to is a composition
type of relationship (in OOP terms) and as such represents the owns
type of relationship rather then uses
in terms of verbs. Therefore each owner
would have its own copy of the same (in terms of value) keyword.
事实上,您可以完全使用您在问题中链接到的文档中的建议来创建自定义 creator
方法并破解它以重用给定键的现有对象,而不仅仅是创建一个新的一.在这种情况下,User
类和 creator
函数的示例代码如下所示:
In fact, you can use exactly the suggestion from the documentation you link to in your question to create a custom creator
method and hack it to reuse existing object for given key instead of just creating a new one. In this case the sample code of the User
class and creator
function will look like below:
def _keyword_find_or_create(kw):
keyword = Keyword.query.filter_by(keyword=kw).first()
if not(keyword):
keyword = Keyword(keyword=kw)
# if aufoflush=False used in the session, then uncomment below
#session.add(keyword)
#session.flush()
return keyword
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String(64))
kw = relationship("Keyword", secondary=lambda: userkeywords_table)
keywords = association_proxy('kw', 'keyword',
creator=_keyword_find_or_create, # @note: this is the
)
这篇关于关联代理 SQLAlchemy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!