代码之家  ›  专栏  ›  技术社区  ›  Igor Komar

contains\u eager和joinedload之间的SQLAlchemy差异

  •  4
  • Igor Komar  · 技术社区  · 6 年前

    SQLAlchemy的区别是什么 contains_eager joinedload 。 我读了 manual 关于contains\u eager,和 manual 关于joinedload。它们都可以用于加载一对多相关行或多对一。

    它们正在生成相同的sql:

    query = session.query(User).\
        outerjoin(adalias, User.addresses).\
        options(contains_eager(User.addresses, alias=adalias)).all()
    
    ...
    
    SELECT
        users.user_id AS users_user_id,
        users.user_name AS users_user_name,
        adalias.address_id AS adalias_address_id,
        adalias.user_id AS adalias_user_id,
        adalias.email_address AS adalias_email_address,
        (...other columns...)
    FROM users
    LEFT OUTER JOIN email_addresses AS email_addresses_1
    ON users.user_id = email_addresses_1.user_id
    
    
    >>> jack = session.query(User).\
    ... options(joinedload(User.addresses)).\
    ... filter_by(name='jack').all()
    
    SELECT
        addresses_1.id AS addresses_1_id,
        addresses_1.email_address AS addresses_1_email_address,
        addresses_1.user_id AS addresses_1_user_id,
        users.id AS users_id, users.name AS users_name,
        users.fullname AS users_fullname,
        users.password AS users_password
    FROM users
    LEFT OUTER JOIN addresses AS addresses_1
        ON users.id = addresses_1.user_id
    WHERE users.name = ?
    ['jack']
    

    有人能给出更具体的代码示例吗?

    1 回复  |  直到 6 年前
        1
  •  6
  •   Ilja Everilä    6 年前

    不要忘记多对多和一对一。区别在于 contains_eager() 您可以向SQLA指示应用于填充关系的一个或多个现有联接。这样你也可以 populate using a filtered subset

    joinedload() 另一方面,尽可能使填充所需的联接完全透明,并且它们不应影响原始查询的结果,如中所述 The Zen of Joined Eager Loading 。换句话说,您不能使用关联关系进行筛选等。