SQLAlchemy连接-无法获得准确的查询

时间:2018-12-12 12:05:06

标签: python sqlalchemy flask-sqlalchemy

我为此感到疯狂。我有一个使用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

笛卡尔积+外部联接,这需要永远运行。

我也尝试过:

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个连接,1个INNER,1个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可能很大,所以不是一种选择。

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

感谢GunnarIlja

的确。在第二个参数中输入条件就可以了。

一起
join(...).options(contains_eager(Event.event_data))

以防止额外的联接。

但是我仍然认为这是一种解决方法,因为条件是“ ON”子句的一部分,而不是“ WHERE”子句的一部分。无论如何,它是可行的。谢谢。

Reference which helped

答案 1 :(得分:-1)

.join()有一个可选的第二个参数,用作on子句。因此,我相信您正在寻找的是:

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