SQLAlchemy join - 无法获得准确的查询

我快要疯了。我有一个使用 SQLAlchemy 的 Flask 应用程序。我想做一个我认为非常简单的查询:


SELECT * FROM event e

LEFT JOIN event_data ed on e.id = ed.event_id

WHERE ed.datetime > '2018-12-01' 

这是我的模型


class Event(db.Model):

    __tablename__ = 'event'

    id = db.Column(db.Integer, primary_key=True)

    #  ... many fields...

    event_data = db.relationship("EventData", back_populates="event", lazy='joined', order_by="desc(EventData.id)")


class EventData(db.Model):

    __tablename__ = 'event_data'

    id = db.Column(db.Integer, primary_key=True)

    event_id = db.Column(db.Integer, db.ForeignKey('event.id'))

    #  ... many fields ...

    event = db.relationship("Event", back_populates="event_data")

当我尝试


Event.query.filter(EventData.datetime>'2018-11-04')

我得到这个 SQL


SELECT every_column_from_event, every_column_from_event_data 

FROM event_data, event 

LEFT OUTER JOIN event_data AS event_data_1 ON event.id = event_data_1.event_id 

WHERE event_data.datetime > %s 

ORDER BY event_data_1.id DESC

笛卡尔积 + OUTER JOIN,需要永远运行。


我也试过:


Event.query.join(EventData).filter(EventData.datetime>'2018-11-04')

这使:


SELECT every_column_from_event, every_column_from_event_data 

FROM event 

INNER JOIN event_data ON event.id = event_data.event_id 

LEFT OUTER JOIN event_data AS event_data_1 ON event.id = event_data_1.event_id 

WHERE event_data.datetime > %s 

ORDER BY event_data_1.id DESC

不再有笛卡尔积,而是 2 个连接,一个 INNER,一个 LEFT OUTER。


如果我将我的加载技术更改为默认的lazy="select",我会得到查询


SELECT every_column_from_event

FROM event 

INNER JOIN event_data ON event.id = event_data.event_id 

WHERE event_data.datetime > %s

这导致了 N+1 选择问题。在我的情况下 N 可能非常大,所以不是一个选项。


非常感谢您的帮助。


白衣非少年
浏览 309回答 2
2回答

千巷猫影

的确。在第二个参数中输入条件就可以了。和...一起join(...).options(contains_eager(Event.event_data))以防止额外加入。但我仍然认为这是一种解决方法,因为条件是“ON”子句的一部分,而不是“WHERE”子句的一部分。无论如何,它有效。谢谢。

慕村225694

.join() 有一个可选的第二个参数,作为一个 on 子句。所以我相信你正在寻找的是:Event.query.join(EventData, EventData.datetime>'2018-11-04')
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python