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
的主要版本匹配,还是只需要一个?让我们继续讨论