2018-06-17 深入理解SQLAlchemy中的backref 是什麼,和舊版back-populate的區別

weixin_33978044發表於2018-06-18

深入理解SQLAlchemy中的backref 是什麼,和舊版back-populate的區別:

看了 網上相關材料如下 : 


https://www.zhihu.com/question/38456789

https://l.jifangcheng.com/p/46 



基本 自悟的總結如下: 

1) backref  是  back-populate的更高階,更簡化版本,是新對舊的替代關係。 

because of  舊版的 back-populate 必須 雙向的,(囉嗦的back-populate 在 有relationship的2個類結構下都宣告) 


而 backref ,可以 單向的宣告,在任何一個 類下,都可以, 

2) ,backref ,一旦使用了,還具備支援 具體巢狀功能的功能: 

看下面的 明明是 1對多關係的 (restaurant -對 history ,即 同一個 restaurant可以 對應 多個 它的history 記錄) 

但有了 backref的描繪後,就可以 用 history['restaurants'] (這個寫法 == 使用restaurant物件,注意這裡的history是histories類的一個例項表) 的方式  直接 取 restaurants 類的表結構裡的col 值

9414891-d22ef3f70221ac68.png


9414891-d7ace5fb480e7627.png


9414891-771c567aa653b5a6.png


9414891-bebdddef6d30b755.png



下面為轉載: 說的更清楚。

https://l.jifangcheng.com/p/46 

SQLAlchemy 中的 backref 和 back_populates

SQLAlchemy 中的 relationship 函式為模型之間的關係提供了一種便利的呼叫方式,backref 引數則對關係提供反向引用的宣告。

下面的例子定義了一個簡單的一對多的關係

class Parent(Base):__tablename__ ='parent'id = Column(Integer, primary_key=True)    children = relationship("Child")class Child(Base):__tablename__ ='child'id = Column(Integer, primary_key=True)    parent_id = Column(Integer, ForeignKey('parent.id'))

一個 Parent 可以有多個 Child,一個 Child 只有一個 Parent

如果我們需要查詢一個 Parent 的 Child,很簡單,因為我們用了 relationship 函式將 Parent 的 children 欄位和 Child表關聯了起來,所以直接取 Parent 例項的 children 屬性就可以了:

parent.children

但是如果我們要查詢一個 Child 的 Parent 要怎麼操作呢?Child 模型裡面有一個 parent_id 欄位,這是一個關聯到其對應 Parent 的外來鍵,我們可以拿到這個 Child 的 Parent 的 id,然後用這個 id 去 Parent 表裡面查詢對應的 Parent 物件:

parent_id = child.parent_id

parent = session.query(Parent).filter_by(id=parent_id).first()

這也是一個方法,不過太麻煩了,SQLAlchemy 為關係的反向引用提供了兩種更為簡單、易用的方法:backref 和 back_populates

backref 引數提供了對關係反向引用的宣告:

class Parent(Base):__tablename__ ='parent'id = Column(Integer, primary_key=True)    children = relationship("Child", backref="parent")

在定義關係的時候使用 backref 引數,該引數使得 Child 物件可以直接使用 backref 引數定義的 parent 值來訪問其對應的 Parent

parent = child.parent

back_populates 可以實現和 backref 同樣的效果,不過在模型的定義上要麻煩一點:

class Parent(Base):__tablename__ ='parent'id = Column(Integer, primary_key=True)    children = relationship("Child", back_populates="parent")class Child(Base):__tablename__ ='child'id = Column(Integer, primary_key=True)    parent_id = Column(Integer, ForeignKey('parent.id'))    parent = relationship("Parent", back_populates="children")

在 Parent 和 Child 中都定義一個相互關聯的 relationship,Parent 可以通過 children 欄位獲取其對應的 Child,Child也可以通過 parent 欄位獲取其對應的 Parent

back_populates 和 backref 達到的效果都是一樣的,對於它們的區別,我的理解是 backref 是隱式地宣告瞭關係反向引用的欄位,back_populates 則是顯式地定義了關係反向引用的欄位。相比於 backref,back_populates 使得模型之間的關係理清晰,所有的關係一目瞭然,不過也比 backref 麻煩一點,各有各的好處。

參考連結

Basic Relationship Patterns — SQLAlchemy 1.2 Documentation

SQLAlchemy淺析

相關文章