彻底搞懂 SQLAlchemy中的 backref

Posted 暮良文王

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了彻底搞懂 SQLAlchemy中的 backref相关的知识,希望对你有一定的参考价值。

教程源码截取:

class User(Base):
    __tablename__ = user
    id = Column(Integer, primary_key=True)
    name = Column(String)

    addresses = relationship("Address", backref="user")


class Address(Base):
    __tablename__ = address
    id = Column(Integer, primary_key=True)
    email = Column(String)
    user_id = Column(Integer, ForeignKey(user.id))

 

简单来说, relationship函数是sqlalchemy对关系之间提供的一种便利的调用方式, backref参数则对关系提供反向引用的声明。
假如没有relationship,我们只能像下面这样调用关系数据:

给定参数User.name,获取useraddresses
def get_addresses_from_user(user_name):
    user = session.query(User).filter_by(name=user_name).first()
    addresses = session.query(Address).filter_by(user_id=user.id).all()
    return addresses

 

 如果在User中使用relationship定义addresses属性的话,
addresses = relationship(Address)

 

 则我们可以直接在User对象中通过addresses属性获得指定用户的所有地址。
def get_addresses_from_user(user_name):
    user = session.query(User).filter_by(name=user_name).first()
    return user.addresses

 

 注意,在上面的addresses属性中我们并没有定义backref属性,
所以我们可以通过User对象获取所拥有的地址,但是不能通过Address对象获取到所属的用户.
>>> u = User()
>>> u.addresses
[]
>>> a = Address()
>>> a.user
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: Address object has no attribute user

 

 但是当我们有从Address对象获取所属用户的需求时,backref参数就派上用场了。
addresses = relationship(Address, backref=user)

 

>>> a = Address()
>>> a.user

 

大致原理应该就是:

sqlalchemy在运行时对Address对象动态的设置了一个指向所属User对象的属性

这样就能在实际开发中使逻辑关系更加清晰,代码更加简洁了。

 

 

一言以蔽之: 

backref用于在关系另一端的类中快捷地创建一个指向当前类对象的属性

 

 

 

 

 

 补充:

db.backref()是你需要对放置 backref的那一边的参数,

(在上例中为 Address类的 .user属性)指定参数时, 使用 backref()函数代替字符串, 常见的有 lazy=‘dynamic‘(禁止自动查询, 用于添加过滤器)。

 backref用于在关系另一端的类中快捷地创建一个指向当前类对象的属性, 而当需要对那个属性指定参数时使用 db.backref()。




 











以上是关于彻底搞懂 SQLAlchemy中的 backref的主要内容,如果未能解决你的问题,请参考以下文章

SQLalchemy 中的 backref 和 back_populate 的概念?

SQLAlchemy学习-5.relationship之backref和back_populates参数

在 SQLAlchemy 中设计我的数据库模式时,我需要多久使用一次“backrefs”?

从 SQLAlchemy 查询中检索不同的 backref 实例

如何正确定义 SQLAlchemy backrefs 以便它们可以反映?

彻底搞懂Python 中的 import 与 from import