如何使属性比较能够编译为 SQLAlchemy 中的 SQL 表达式?

Posted

技术标签:

【中文标题】如何使属性比较能够编译为 SQLAlchemy 中的 SQL 表达式?【英文标题】:How can I make property comparison able to be compiled to SQL expression in SQLAlchemy? 【发布时间】:2013-10-15 08:44:06 【问题描述】:

有两个表,表 A 的一列指向另一个表 B 的主键。

但是它们放在不同的数据库中,所以我不能用外键配置它们。

无法通过relationship()配置,所以我手动实现了属性属性。

class User(Base):
    __tablename__ = 'users'
    id = Column(BigInteger, id_seq, primary=True)
    name = Column(Unicode(256))


class Article(Base):
    __tablename__ = 'articles'
    __bind_key__ = 'another_engine'
    # I am using custom session configures bind
    # each mappers to multiple database engines via this attribute.

    id = Column(BigInteger, id_seq, primary=True)
    author_id = Column(BigInteger, nullable=False, index=True)
    body = Column(UnicodeText, nullable=False)

    @property
    def author(self):
        _session = object_session(self)
        return _session.query(User).get(self.author_id)

    @author.setter
    def author(self, user):
        if not isinstance(user, User):
            raise TypeError('user must be a instance of User')
        self.author_id = user.id

此代码适用于简单的操作。但它会导致脏查询,使 SQLAlchemy 的功能毫无意义。

如果通过relationship()(例如query.filter(author=me))配置的代码会很简单(例如query.filter(author_id=me.id))。

关系(例如连接)相关功能永远无法用于查询构建。

我是否可以至少在构建查询条件时使用属性属性(filter()/filter_by())?

【问题讨论】:

【参考方案1】:

你仍然可以在这里使用关系。如果你坚持“延迟加载”,它会在加载数据库A中的lead item后查询数据库B中的相关项目。你可以在Column中放置一个ForeignKey()指令,即使没有真正的数据库。或者你可以直接使用primaryjoin:

class User(Base):
    __tablename__ = 'users'
    id = Column(BigInteger, id_seq, primary=True)
    name = Column(Unicode(256))


class Article(Base):
    __tablename__ = 'articles'
    __bind_key__ = 'another_engine'

    id = Column(BigInteger, id_seq, primary=True)
    author_id = Column(BigInteger, nullable=False, index=True)
    body = Column(UnicodeText, nullable=False)

    author = relationship("User", 
                primaryjoin="foreign(Article.author_id) == User.id")

【讨论】:

哦,谢谢!无法使用 join/joinedload,因为编译后的查询将在单个数据库引擎中执行,该数据库引擎为执行查询的主映射器而映射。但是访问关系属性,在过滤表达式中使用它的效果非常好!

以上是关于如何使属性比较能够编译为 SQLAlchemy 中的 SQL 表达式?的主要内容,如果未能解决你的问题,请参考以下文章

如何强制 MSBuild 编译为 32 位模式?

如何在 webpack 中加载 Pug 模板而不编译为 HTML?

如何将javascript代码编译为c++或java

为什么C / C ++编译器并不总是使++成为原子?

从无到有构建一个Mini Linux

Pyinstaller编译为exe