backref lazy ='dynamic' - 不支持对象填充 - 无法应用急切加载

时间:2015-04-26 05:30:49

标签: python flask sqlalchemy flask-sqlalchemy

如何在指定的2个日期之间获得Planes Bookings。我需要将Bookings过滤下来,只有在两个日期之间才会被包含在内。我试过这个,但得到错误:'Plane.bookings' does not support object population - eager loading cannot be applied.

为什么会出现此错误以及如何解决?

planes = (db.session.query(Plane)
             .join(Booking)
             .filter(Booking.start_date >= date)
             .options(contains_eager(Plane.bookings)))

模特:

class Booking(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        start_date = db.Column(db.DateTime)
        end_date = db.Column(db.DateTime)

        person_id = db.Column(db.Integer, db.ForeignKey('person.id'))
        person = db.relationship('Person', foreign_keys=[person_id], backref=db.backref('bookings', lazy='dynamic'))

        instructor_id = db.Column(db.Integer, db.ForeignKey('person.id'))
        instructor = db.relationship('Person', foreign_keys=[instructor_id], backref=db.backref('instructor_bookings', lazy='dynamic'))

        plane_id = db.Column(db.Integer, db.ForeignKey('plane.id'))
        plane = db.relationship('Plane', backref=db.backref('bookings', lazy='dynamic'))

        def __init__(self, start_date, end_date, plane_id, instructor_id, person_id):
            self.start_date = start_date
            self.end_date = end_date
            self.plane_id = plane_id
            self.instructor_id = instructor_id
            self.person_id = person_id

        def __repr__(self):
            return '<Booking... %r>'

        def as_dict(self):
           return {c.name: getattr(self, c.name) for c in self.__table__.columns}


    class Plane(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(80))
        description = db.Column(db.String(120))

        def __init__(self, name, description):
            self.name = name
            self.description = description

        def __repr__(self):
            return '<Plane... %r>'

        def as_dict(self):
           return {c.name: getattr(self, c.name) for c in self.__table__.columns}

1 个答案:

答案 0 :(得分:6)

错误消息告诉您确切的“错误”:无法急切加载lazy='dynamic'关系。动态关系产生新的查询,而不是集合(列表)。预加载动态关系没有意义,因为动态关系的整个点是能够构造其他查询。

使用动态关系在访问时过滤预订。这不是最优的,因为每个飞机需要查询才能获得预订。

planes = Plane.query.join(Plane.bookings).filter(Booking.start_date >= date)
for plane in planes:
    bookings = plane.bookings.filter(Booking.start_date >= date)

更有可能的是,你想要一种非动态的关系。只需从关系的backref中删除lazy='dynamic'即可。如果您为已过滤的联接传递contains_eager,则生成的集合将只包含已过滤的项目。

plane = db.relationship(lambda: Plane, backref='bookings')
# ...
planes = Plane.query.join(Plane.bookings
).filter(Booking.start_date >= date
).options(db.contains_eager(Plane.bookings))

另请注意,没有什么可以阻止您定义两个关系到同一个集合,一个是动态的,一个不是,使用当时正在进行的操作所需的任何一个。