关联代理 SQLAlchemy [英] Association Proxy SQLAlchemy

查看:21
本文介绍了关联代理 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆