flask-sqlalchemy-在不同情况下变懒惰

时间:2018-09-10 01:11:34

标签: flask sqlalchemy flask-sqlalchemy

以文档中的示例

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)
    addresses = db.relationship('Address', lazy='dynamic',
        backref=db.backref('person', lazy='select'))

我们只能在构建模型时将 lazy 参数设置为 relationship 。但是我发现没有文件显示实例化后如何更改它。

在我的大多数情况下

user = User.query.first()
addresses = user.addresses.filter(is_del=0).all()

是一对多或

wallet = user.wallet

是一对一模型,我只是将 lazy 设置为 dynamic或选择,以使该模型仅获取我需要的数据。

但是最近我想使用Admin Front-end页面导出数据库中的数据。

user_list = UserModel.query.all()
for x in user_list:
    item = {
        "ID": x.id if x.id else ''
    }
    if 'basic' in fields or is_all_field == 1:
        ex_item = {
            "Email": x.base.account,
            "Full Name": x.base.full_name,
            "Display Name": x.display_name if x.display_name else '',
            "Phone Number": x.base.phone_number if x.base.phone_number else '',
            "Status": status_map(x.is_sharer,x.is_block,x.status_id)
            "Register Time": x.create_date.strftime('%Y-%m-%d %H:%M:%S') if x.create_date else ''
        }
        item = {**item, **ex_item}
    if ......
    ........

如果我继续使用select和dynamic作为懒惰。这将非常慢,因为父查询每次使用子查询时,每次循环都会访问数据库。

我使用"Full Name": x.base.full_name之类的单个字段来测试所有用户数据,以测试 select joined 之间的速度。 选择获得53秒,加入获得0.02秒。

是否可以基于不更改原始模型来更改 lazy 参数?

2 个答案:

答案 0 :(得分:1)

因此,基本上,如果您使用的是lazy=' select',延迟加载,并且想切换到joinload以优化查询,请使用以下命令:

from sqlalchemy.orm import joinedload  # import the joinedload 
user_list = db.session.query(UserModel).options(joinedload("person"))  # running a joinedload which will give you access to all attributes in parent and child class 
for x in user_list: 
    # now use x.account directly

答案 1 :(得分:0)

根据documentation,您可以使用options定义所需的加载类型。我相信它将覆盖您在关系中定义的默认值

有用的链接

Joined Loads

Select Loads

Lazy Load