教程源碼截取:
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,獲取該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
如果在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()。