文章内容

2024/7/11 2:00:45,作 者: 黄兵

SQLAlchemy 中 lazy=True 和 lazy='dynamic' 有什么区别

在 SQLAlchemy 中,lazy 参数用于指定如何加载关联的关系。lazy=Truelazy='dynamic' 有显著的区别,尤其是在性能和使用场景上。

lazy=True

lazy=True(其实等同于 lazy='select')时,关联的记录在第一次访问关联属性时会立即从数据库中加载。这种加载方式适用于大多数情况,并且很直观。

class Parent(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    children = db.relationship('Child', backref='parent', lazy=True)  # or lazy='select'

优点:

  • 简单直接,适用于一般情况下的关联数据加载。

缺点:

  • 如果关联的记录数量很大,可能会导致性能问题,因为每次访问关联属性都会立即执行一条查询来加载所有关联记录。

lazy='dynamic'

lazy='dynamic' 时,访问关联属性时不会立即加载记录,而是返回一个查询对象。只有在实际执行查询(如调用 .all().first() 等)时才会从数据库中加载记录。这种方式非常适合需要对关联数据进行进一步过滤或分页的情况。

class Parent(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    children = db.relationship('Child', backref='parent', lazy='dynamic')

优点:

  • 延迟加载,避免一次性加载大量数据。
  • 提供更大的灵活性,可以对关联数据进行进一步的查询操作,如过滤、排序和分页。

缺点:

  • 需要显式调用查询方法来获取数据,增加了代码复杂度。

示例对比

使用 lazy=True

parent = Parent.query.get(1)
# Access children immediately loads all children
children = parent.children  # This executes a query to load all children

使用 lazy='dynamic'

parent = Parent.query.get(1)
# Accessing children returns a query object, not the actual records
children_query = parent.children  # This does NOT execute a query
# Execute query to get all children
all_children = children_query.all()  # Now it executes a query
# Execute query with filtering
some_children = children_query.filter_by(name='John').all()  # Executes a query with filter

使用场景建议

  • lazy=True: 适用于关联数据量较少或关联数据总是需要被加载的场景。
  • lazy='dynamic': 适用于关联数据量较大或需要对关联数据进行进一步查询操作的场景。

根据你的具体需求选择合适的 lazy 加载方式,可以在性能和灵活性之间取得平衡。


其它相关推荐:

1、sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (1138, 'Invalid use of NULL value')

2、SQLAlchemy 重复过滤查询

3、SQLAlchemy 中 outerjoin() 和 join() 的区别

4、SQLAlchemy 查询去重

5、SQLAlchemy 插入种子数据或默认数据方法总结

分享到:

发表评论

评论列表