我可以在 SQLAlchemy ORM 中使用动态关系(或视图)吗?

Posted

技术标签:

【中文标题】我可以在 SQLAlchemy ORM 中使用动态关系(或视图)吗?【英文标题】:Can I use dynamic relationships (or VIEWS) in SQLAlchemy ORM? 【发布时间】:2013-11-15 13:32:03 【问题描述】:

我正在寻找一种方法,以便关系只使用表格的某些行,而不是整个表格。

我正在考虑使用 视图 而不是原始表作为关系的基础。 view 仅包含来自原始表的一组过滤行。

示例

我想收集来自不同设备和不同用户的几个播放器的歌曲统计信息(评分、播放次数、上次播放时间)。我使用 Python 和 SQL Alchemy。

我想出了下面的表格布局(你可以看看code for the objects和SQL for the tables):

问题

对于每个Song 对象,我可以轻松获得所有相关的 Stats 对象。但大多数时候我只想要其中一些。我只想要那些与一个或多个Commit 相关的SongStats,例如。仅来自给定用户的所有提交或某个特定提交的数据。

所以我需要一些方法来过滤歌曲对象的统计数据。

我不确定如何存档。

我应该使用一些自定义查询吗?但是我应该把它放在哪里以及如何放置?另外:虽然这可能会给我我想要的数据(select path, rating... over the three joined tables 或 something along those lines),但我不会取回对象。

我正在考虑在stats 表上使用视图,只包含与给定commits 匹配的行。视图必须通过动态创建,因此可以过滤不同的提交。而不是将此视图用作从songsstats 的关系的基础。但我不知道该怎么做。

那么:关于如何解决这个问题的任何想法?

或者如何解决这个问题?

【问题讨论】:

现在我使用像this这样的直接SQL查询。它给了我数据,但我更喜欢 Song 对象,并且只有过滤后的 Stats 映射到它,所以我可以在 Song 对象上进一步处理它们。 我知道如何实现这一点,但我需要更多细节。这种观点是暂时的还是物化的?你在使用 Postgresql 吗?因此,您希望在 python 中第一次使用 commit_id 查询 Stats 时创建一个视图。该查询的所有后续查询都将使用该视图,而不是原始表? 【参考方案1】:

你可以试试这样的:

from sqlalchemy.orm import object_session
# defined inside of your Song class
def stats_by_commit(self,commit):
    #this could also be implemented as a join
    return object_session(self).query(Stat)\
           .filter(Stat.song_id == self.song_id,Stat.commit_id == Commit.commit_id)

用法:

commit = db_session.query(Commit).filter_by(id=1)
for song in db_session.query(Song).filter_by(path='some_song_path'):
    for stat in song.stats_by_commit(self,commit):
        print stat.rating

【讨论】:

酷,我以前从未听说过object_session。我现在无法测试您的代码,但它看起来不错。虽然这更像是我现在使用的解决方法,而不是我正在寻找的东西。我试图让问题更清楚。 我不确定我是否完全理解您为什么要使用视图而不是查询。一些动机可能会有所帮助......

以上是关于我可以在 SQLAlchemy ORM 中使用动态关系(或视图)吗?的主要内容,如果未能解决你的问题,请参考以下文章

SQLAlchemy 中的动态类创建

动态 SQLAlchemy ORM 关系生成

如何使用 SQLAlchemy Postgres ORM 的声明性基础动态创建具有列名和字典约束的表?

sqlalchemy 最简易用法

SQLAlchemy ORM 重构器的替代方案

如何从 SQLAlchemy ORM 会话中查询预先存在的表?