Python SQLAlchemy:如何访问两个表中的关系
我正在开发一个系统来跟踪当前的设备固件,并将其与推荐的版本进行比较。模型和代码简化如下。我有三种型号:Python SQLAlchemy:如何访问两个表中的关系,python,sqlalchemy,flask-sqlalchemy,Python,Sqlalchemy,Flask Sqlalchemy,我正在开发一个系统来跟踪当前的设备固件,并将其与推荐的版本进行比较。模型和代码简化如下。我有三种型号:Version、FirmwareHistory和VersionRecommendation Version具有属性major、minor、patch和bugfix FirmwareHistory已更改日期,版本,以及设备 版本建议有日期,版本,更改的用户,首选 VersionRecommendation表可以列出多个版本作为首选,因为我们支持多个主要分支。现在,我正试图交叉引用Firmwar
Version
、FirmwareHistory
和VersionRecommendation
具有属性Version
、major
、minor
和patch
李>bugfix
已更改FirmwareHistory
,日期
,以及版本
李>设备
有版本建议
,日期
,版本
,更改的用户
首选
VersionRecommendation
表可以列出多个版本作为首选,因为我们支持多个主要分支。现在,我正试图交叉引用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()
但是,我还想访问FirmwareHistory
的Version
属性和VersionRecommendation
以检查mair
属性。并且只返回版本major
相同的结果
基本上:
请给出一个结果,其中FirmwareHistory
和VersionRecommendation
都具有相同的版本。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
或VersionRecommendation
引用版本,只需将其作为模型访问即可:
session.query(FirmwareHistory,func.max(FirmwareHistory.date),versionRecommension)\
.从(固件历史记录)中选择\
.join(版本)\
.join(版本推荐)\
.filter(VersionRecommension.preferred==True)\
.group_by(FirmwareHistory.device_id)\
.all()
或者,如果确实希望避免额外的联接,可以显式指定联接条件。不过,我不会这么做,因为PostgreSQL通常足够聪明,可以对其进行优化
session.query(FirmwareHistory,func.max(FirmwareHistory.date),versionRecommension)\
.从(固件历史记录)中选择\
.join(versionRecommension,FirmwareHistory.version\u id==versionRecommension.version\u id)\
.filter(VersionRecommension.preferred==True)\
.group_by(FirmwareHistory.device_id)\
.all()
好的!
使用别名“版本”使其正常工作
from sqlalchemy.orm import aliased
...
firmware_version = aliased(Version)
recommended_version = aliased(Version)
session().query(FirmwareHistory, func.max(FirmwareHistory.date), VersionRecommendation)\
.filter(VersionRecommendation.preferred == True)\
.group_by(FirmwareHistory.device_id)\
.join(firmware_version, FirmwareHistory.version_id==firmware_version.id)\
.join(recommended_version, VersionRecommendation.version_id==recommended_version.id)\
.filter(recommended_version.major == firmware_version.major)\
.all()
有了这个,我得到了当前版本和运行相同专业的推荐版本。我将如何比较FirmwareHistory和VersionRecommendation的主要列?为此,我需要更多的上下文。无法执行当前查询,因为MAX(DATE)
需要GROUPBY子句中的所有非分组元素。您想将其作为一列,还是只想查看FirmwareHistory
的最后一个条目?您希望所有VersionRecommendation
s与FirmwareHistory
的主要版本匹配,还是只需要一个?让我们继续讨论