Flask 資料庫多對多自引用關係

2021-07-11 17:06:56 字數 2327 閱讀 7221

上篇介紹的多對多關係是兩個模型是之間的多對多關係,關聯表聯接的是兩個明確的實體,還有些情況下只有乙個模型,與自己之間存在多對多關係。比如使用者之間的關注。表示使用者關注其他使用者時,只有使用者乙個實體,沒有

第二個實體。如果關係中的兩側都在同乙個表中, 這種關係稱為自引用關係。

在關注中, 關係的左側是使用者實體,可以稱為「關注者」;關係的右側也是使用者實體,但這些是「被關注者」。從概

念上來看,自引用關係和普通關係沒什麼區別,只是不易理解。下圖 是自引用關係的資料庫**,表示使用者之間的關注。

本例的關聯表是 follows,其中每一行都表示乙個使用者關注了另乙個使用者。圖中左邊表示的一對多關係把使用者和 follows 表中的一組記錄聯絡起來,使用者是關注者。圖中右邊表示的一對多關係把使用者和 follows 表中的一組記錄聯絡起來,使用者是被關注者。

class follow(db.model):

__tablename__ = 'follows'

follower_id = db.column(db.integer, db.foreignkey('users.id'),primary_key=true)

followed_id = db.column(db.integer, db.foreignkey('users.id'),primary_key=true)

timestamp = db.column(db.datetime, default=datetime.utcnow)

sqlalchemy 不能直接使用這個關聯表,因為如果這麼做程式就無法訪問其中的自定義字段。相反地, 要把這個多對多關係的左右兩側拆分成兩個基本的一對多關係,而且要定義成標準的關係。**如下 所示。

class user(usermixin, db.model):

# ...

followed = db.relationship('follow',foreign_keys=[follow.follower_id],

backref=db.backref('follower', lazy='joined'),

lazy='dynamic',

cascade='all, delete-orphan')

followers = db.relationship('follow',foreign_keys=[follow.followed_id],

backref=db.backref('followed', lazy='joined'),

lazy='dynamic',

cascade='all, delete-orphan')

在這段**中, followed 和 followers 關係都定義為單獨的一對多關係。注意,為了消除外來鍵間的歧義, 定義關係時必須使用可選引數 foreign_keys 指定的外來鍵。而且,db.backref() 引數並不是指定這兩個關係之間的引用關係,而是回引 follow 模型。回引中的 lazy 引數指定為 joined。這個 lazy 模式可以實現立即從聯結查詢中載入相關對

象。例如,如果某個使用者關注了 100 個使用者,呼叫 user.followed.all() 後會返回乙個列表,其中包含 100 個 follow 例項,每乙個例項的 follower 和 followed 回引屬性都指向相應的使用者。設定為 lazy='joined' 模式,就可在一次資料庫查詢中完成這些操作。如果把lazy 設為預設值 select,那麼首次訪問 follower 和 followed 屬性時才會載入對應的使用者,

而且每個屬性都需要乙個單獨的查詢, 這就意味著獲取全部被關注使用者時需要增加 100 次額外的資料庫查詢。

這兩個關係中, user 一側設定的 lazy 引數作用不一樣。 lazy 引數都在「一」這一側設定,返回的結果是「 多」這一側中的記錄。上述**使用的是 dynamic,因此關係屬性不會直接返回記錄,而是返回查詢物件,所以在執行查詢之前還可以新增額外的過濾器。

cascade 引數配置在父物件上執行的操作對相關物件的影響。比如,層疊選項可設定為:將使用者新增到資料庫會話後, 要自動把所有關係的物件都新增到會話中。層疊選項的預設值能滿足大多數情況的需求, 但對這個多對多關係來說卻不合用。刪除物件時,預設的層疊行為是把物件聯接的所有相關物件的外來鍵設為空值。 但在關聯表中,刪除記錄後正確的行為應該是把指向該記錄的實體也刪除, 因為這樣能有效銷毀聯接。這就是層疊選項值delete-orphan 的作用。

cascade 引數的值是一組由逗號分隔的層疊選項,這看起來可能讓人有點困惑,但 all 表示除了 delete-orphan 之外的所有層疊選項。設為 all,delete-orphan 的意思是啟用所有預設層疊選項,而且還要刪除孤兒記錄。

flask 定義資料庫關係(多對多)

多對多 我們使用學生和老師來演示多對多關係 每個學生有多個老師,每個老師有多個學生。多對多關係示意圖如下 在例項程式中,student類表示學生,teacher類表示老師。在這兩個模型之間建立多對多關係後,我們需要在student類中新增乙個集合關係屬性teachers,呼叫它可以獲取某個學生的多個...

flask多對多的正向 反向引用

flask多對多關係的查詢 新增 刪除 角色模型 class role db.model tablename role r id db.column db.integer,autoincrement true primary key true r name db.column db.string 1...

Flask 資料庫高階多對多關係

之前介紹了多對多關係 在之前介紹的多對多關係中,關聯表就是乙個簡單的表,不是模型,sqlalchemy 會自動接管這個表。多對多關係可以分解成原表和關聯表之間的兩個一對多關係。這個表裡面儲存了原表的兩個主鍵作為自己的聯合主鍵。存在的問題 因為在這種關聯表裡操作的時候都是物件導向的,新增,刪除等操作都...