python - SQLAlchemy:如何访问两个表中的关系
问题描述
我正在开发一个系统来跟踪当前的设备固件并将其与推荐的版本进行比较。模型和代码已简化如下。我有三个模型Version
:FirmwareHistory
和VersionRecommendation
。
Version
具有属性major
,minor
,patch
和bugfix
;FirmwareHistory
有date_changed
,version
, 和device
;VersionRecommendation
有date
,version
,user_who_changed
和preferred
.
该VersionRecommendation
表可以列出多个Versions
作为首选,因为我们支持多个主要分支。现在我正在尝试交叉引用FirmwareHistory
并VersionRecommendation
查看设备是否正在运行推荐的版本或更高版本。
以下查询为我提供了运行推荐版本的所有设备的列表。
session.query(FirmwareHistory, func.max(FirmwareHistory.date), VersionRecommendation)\
.filter(VersionRecommendation.preferred == True)\
.group_by(FirmwareHistory.device_id)\
.filter(FirmwareHistory.version_id == VersionRecommendation.version_id)
.all()
但是我也想访问Version
属性FirmwareHistory
并VersionRecommendation
检查major
属性。并且只返回版本major
相同的结果。
基本上:给我一个结果,其中FirmwareHistory
和VersionRecommendation
两者都相同Version.major
我试过了:
session().query(FirmwareHistory, func.max(FirmwareHistory.date), VersionRecommendation)\
.filter(VersionRecommendation.preferred == True)\
.group_by(FirmwareHistory.device_id)\
.filter(VersionRecommendation.version.major == FirmwareHistory.version.major)\
.all()
但这给了我一个属性错误:AttributeError:与 SoftwareRevision.version 关联的“InstrumentedAttribute”对象和“Comparator”对象都没有属性“major”
我尝试加入这两个版本,但 SQLAlchemy 因列名而感到困惑:
session.query(FirmwareHistory, func.max(FirmwareHistory.date), VersionRecommendation)\
.filter(VersionRecommendation.preferred == True)\
.group_by(FirmwareHistory.device_id)\
.join(FirmwareHistory.version)\
.join(VersionRecommendation.version)\
.filter(FirmwareHistory.version_id == VersionRecommendation.version_id)
.all()
有没有办法做到这一点?
解决方案
不要通过FirmwareHistory
or引用版本VersionRecommendation
,而只是将其作为模型访问:
session.query(FirmwareHistory, func.max(FirmwareHistory.date), VersionRecommendation)\
.select_from(FirmwareHistory)\
.join(Version)\
.join(VersionRecommendation)\
.filter(VersionRecommendation.preferred == True)\
.group_by(FirmwareHistory.device_id)\
.all()
或者,如果您真的想避免额外的连接,您可以明确指定连接条件。不过,我不会这样做,因为 PostgreSQL 通常足够聪明,可以将其优化掉。
session.query(FirmwareHistory, func.max(FirmwareHistory.date), VersionRecommendation)\
.select_from(FirmwareHistory)\
.join(VersionRecommendation, FirmwareHistory.version_id == VersionRecommendation.version_id)\
.filter(VersionRecommendation.preferred == True)\
.group_by(FirmwareHistory.device_id)\
.all()
推荐阅读
- python - 如何从用 pygame 编写的游戏创建可执行文件
- pandas - 管道中的熊猫 groupby + ngroup
- python - 如何计算 DataFrame 列中的单词?
- java - Java outputStream "\n" 在 cmd 上没有按预期工作
- spring-boot - 我想在 Spring boot JPA 和 Angular 7 中选择用户指定的特定列
- ajax - Ajax发布请求在部署时发送空数据但在asp.net mvc中本地工作
- mqtt - MQTT 和 OPC-UA(发布/订阅)有什么区别
- asp.net - XML 格式的 xmlns:i 和 xmlns:xsi 属性有什么区别?以及如何在 SQL Server 中查询 xmlns:i 值?
- node.js - 使用 npm install --no-bin-links 安装 package.json 但在运行构建时遇到问题
- tensorflow - 在 build.gradle 依赖项中声明特定 tf-nightly 版本的语法?