SQLAlchemy оставил внешнее соединение с подзапросом

Я некоторое время пытался понять, что не так с этим запросом, и я совершенно озадачен.

По сути, у меня есть две таблицы: родительская таблица с именем MainHeatMap и таблица дочерних элементов с именем MainHeatMapReportLog (структура ниже).

class MainHeatMap(Base):
    __tablename__ = 'MainHeatMap'
    MapID = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
    Abbrev = Column(String(6), nullable=False, unique=True)  #ID for API
    Name = Column(String(20), unique=True, nullable=False)
    Visible = Column(Boolean(), default=True)
    Alert = Column(Boolean(), default=False)
    ManualCancelAlert = Column(Boolean(), default=False)
    Reports = relationship('MainHeatMapReportLog',
                           primaryjoin='MainHeatMap.MapID == MainHeatMapReportLog.MapID',
                           backref='Map', lazy='dynamic'
                           )

    def __init__(self, Name, Abbrev, ManualCancelAlert=False):
        self.Name = Name
        self.Abbrev = Abbrev
        self.ManualCancelAlert = ManualCancelAlert

class MainHeatMapReportLog(Base): 
    __tablename__ = 'MainHeatMapReportLog'
    LogID = Column(Integer, primary_key=True, nullable=False)
    MapID = Column(Integer, ForeignKey('MainHeatMap.MapID'), nullable=False)
    Status = Column(String(8), index=True)
    LogDate = Column(TIMESTAMP(), nullable=False, default=datetime.utcnow())
    ReportingApplication = Column(String(15), nullable=False)
    Message = Column(String(255))

    def __init__(self, Status, ReportingApplication, Message):
        self.Status = Status
        self.ReportingApplication = ReportingApplication
        self.Message = Message

Я пытаюсь создать запрос, который дает мне каждую запись, где для параметра «Видимость» установлено значение «Истина» в таблице MainHeatMap, а также последнюю дочернюю запись (если есть) для каждой в таблице MainHeatMapReportLog.

SQL для этого запроса будет:

SELECT A.MapID, A.Abbrev, A.Name, A.Visible, A.Alert, A.ManualCancelAlert, B.ReportDate
FROM MainHeatMap A
LEFT JOIN (
            SELECT MapID, Max(LogDate) as ReportDate
            FROM MainHeatMapReportLog
            GROUP BY MapID
            ) B
ON A.MapID = B.MapID
WHERE A.Visible = 1

Однако, когда я пытаюсь запустить следующие строки, я получаю сообщение об ошибке

Объект «Псевдоним» не имеет атрибута «MapID»

LatestReportDate = Session.query(models.MainHeatMapReportLog.MapID,
                             func.max(models.MainHeatMapReportLog.LogDate).label('ReportDate')
                             ).group_by(models.MainHeatMapReportLog.MapID).subquery()

LatestReports = Session.query(models.MainHeatMap).outerjoin(
    (LatestReportDate, (models.MainHeatMap.MapID==LatestReportDate.MapID))
).filter(models.MainHeatMap.Visible==True).all()

Подзапрос, если он изменен на метод .all(), работает нормально, поэтому он должен быть таким, каким я пытаюсь объединить таблицу и подзапрос вместе. Мой google-fu предполагает, что псевдонимы используются для самостоятельных соединений, но я не понимаю ссылку в этом случае, возможно, я неправильно называю models.MainHeatMap?

Если бы кто-нибудь мог указать мне в правильном направлении, это было бы очень признательно.


person Devasta    schedule 31.10.2014    source источник
comment
Вместо этого попробуйте models.MainHeatMap.MapID==LatestReportDate.c.MapID в условии join.   -  person van    schedule 31.10.2014
comment
Также взгляните на недавний очень похожий вопрос и ответ [stackoverflow.com/a/26483320/99594], где вы можете загрузить весь экземпляр связанной таблицы (MainHeatMapReportLog), а не только поле. Это также решает проблему дублирования результатов, если у вас есть несколько MainHeatMapReportLog с одним и тем же последним LogDate.   -  person van    schedule 31.10.2014
comment
Привет, Ван. Большое спасибо за ваш ответ, я сейчас попробую и просматриваю предоставленную вами ссылку. Другой вопрос, если вы не возражаете: что делает «с», который я включаю в запрос?   -  person Devasta    schedule 31.10.2014
comment
Это псевдоним для columns, см. sqlalchemy.sql.expression.Select.c документация.   -  person van    schedule 01.11.2014
comment
Еще раз спасибо, Ван! :)   -  person Devasta    schedule 01.11.2014