简单来说, relationship
函数是sqlalchemy
对关系之间提供的一种便利的调用方式, backref
参数则对关系提供反向引用的声明。
1、假如没有relationship
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String)
class Address(Base):
__tablename__ = 'address'
id = Column(Integer, primary_key=True)
email = Column(String)
user_id = Column(Integer, ForeignKey('user.id'))
我们只能像下面这样调用关系数据:
给定参数User.name,获取该user的addresses
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
2、如果在User中使用relationship定义addresses属性的话
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String)
addresses = relationship("Address")#没有定义 backref
class Address(Base):
__tablename__ = 'address'
id = Column(Integer, primary_key=True)
email = Column(String)
user_id = Column(Integer, ForeignKey('user.id'))
则我们可以直接在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
参数就派上用场了。
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'))
>>> a = Address()
>>> a.user
大致原理应该就是:
sqlalchemy
在运行时对Address
对象动态的设置了一个指向所属User
对象的属性,这样就能在实际开发中使逻辑关系更加清晰,代码更加简洁了。
简单的说就是:
backref
用于在关系另一端的类中快捷地创建一个指向当前类对象的属性。
补充:
db.backref()
是你需要对放置backref
的那一边的参数,
(在上例中为Address
类的.user
属性)指定参数时, 使用backref()
函数代替字符串, 常见的有lazy='dynamic'
(禁止自动查询, 用于添加过滤器)。
backref
用于在关系另一端的类中快捷地创建一个指向当前类对象的属性, 而当需要对那个属性指定参数时使用 db.backref()
。
网友评论