多對多
我們使用學生和老師來演示多對多關係:每個學生有多個老師,每個老師有多個學生。多對多關係示意圖如下:
在例項程式中,student類表示學生,teacher類表示老師。在這兩個模型之間建立多對多關係後,我們需要在student類中新增乙個集合關係屬性teachers,呼叫它可以獲取某個學生的多個老師,而不同的學生可以和同乙個老師建立關係。
在一對一關係中,我們可以在「多」這一側新增外來鍵指向「一」這一側,外來鍵只能儲存乙個記錄,但是在多個關係中,每乙個記錄都可以與關係另一側的多個記錄建立關係,關係兩側的模型都需要儲存一組外來鍵。在sqlalchemy中,要想表示多對多關係,除了關係兩側的模型外,我們還需要建立乙個關聯表(association table)。關聯表不儲存資料,只用來儲存關係兩側模型的外來鍵對應關係。
association_table = db.table('關聯表使用db.table類定義,傳入的第乙個引數是關聯表的名稱。我們在關聯表中定義了兩個外來鍵字段:teacher_id欄位儲存teacher類的主鍵,student_id儲存student類的主鍵。借助關聯表這個中間人儲存的外來鍵對,我們可以把對對多關係分化成兩個一對多關係,如下所示:association',
db.column(
'student_id
', db.integer, db.foreignkey('
student.id
')),
db.column(
'teacher_id
', db.integer, db.foreignkey('
teacher.id'))
)class
student(db.model):
id = db.column(db.integer, primary_key=true)
name = db.column(db.string(70), unique =true)
grade = db.column(db.string(20))
teachers = db.relationship('
teacher',
secondary =association_table,
back_populates = '
students
') #
collection
def__repr__
(self):
return
'' %self.name
class
teacher(db.model):
id = db.column(db.integer, primary_key =true)
name = db.column(db.string(70), unique =true)
office = db.column(db.string(20))
#back_populates, 定義雙向關係
#back_populates引數的值需要設為關係另一側的關係屬性名
students = db.relationship('
student',
secondary =association_table,
back_populates = '
teachers
') #
collection
當我們需要查詢某個學生記錄的多個老師時,我們先通過學生和關聯表的一對多關係查詢多有包含該學生的關聯表記錄,然後後就可以從這些記錄中再進一步獲取每個關聯表記錄包含的老師記錄。以上圖的隨機資料為例,假設學生記錄的id為1,那麼通過查詢關聯表中student_id欄位為1的記錄,就可以獲取到對應的teacher_id值(分別為3和4),通過外鍵值就可以在teacher表裡獲取id為3和4的記錄,最終,我們就獲取到id為1的學生記錄相關聯的所有老師記錄。
我們在student類中定義乙個teachers關係屬性用來獲取老師集合。在多對多關係中定義關係函式,除了第乙個引數是關係另一側的模型名稱外,我們還需要新增乙個secondary引數,把這個值設為關聯的名稱。
為了便於實現真正的多對多關係,我們需要建立雙向關係。建立雙向關係後,多對多關係會變得更加直觀。在student類上的teachers集合屬性會返回所有關聯的老師記錄,而在teacher類上的students集合屬性會返回所有相關的學生記錄
關聯表有sqlalchemy接管,它會幫我們管理這個表:我們只需要像往常一樣通過操作關係屬性來建立或解除關係,sqlalchemy會自動在關聯表中建立或刪除對應的關聯表記錄,而不用手動操作關聯表。
同樣的,在多對多關係中我們也只需要在關係的一側操作關係。當為學生a的teachers新增老師b後,呼叫老師b的students屬性時返回的學生記錄也會包含學生a,反之亦同。
>>> s1 = student(name = 'xiaxiaoxu')
>>> t1 = teacher(name = '
xufengchai')
>>> s2 = student(name = '
xiayuze')
>>> t2 = teacher(naem = '
xulei')
>>> t2 = teacher(name = '
xulei')
>>>s1
'xiaxiaoxu
'>
>>>s2
'xiayuze
'>
>>>t1
'xufengchai
'>
>>>t2
'xulei
'>
>>>db.session.add(s1)
>>>db.session.add(s2)
>>>db.session.add(t1)
>>>db.session.add(t2)
>>>db.session.commit()
>>>s1.teachers
>>> s1.teacher_id =1
>>> s2.teacher_id =2
>>> t1.student_id = 1
>>> t2.student_id = 2
>>>s1.teachers
>>>db.session.commit()
>>>s1.teachers['
xufengchai
'>, '
xulei
'>]
>>>t1.students['
xiaxiaoxu
'>, '
xiaxiaoxu
'>, '
xiayuze
'>]
Flask 資料庫多對多自引用關係
上篇介紹的多對多關係是兩個模型是之間的多對多關係,關聯表聯接的是兩個明確的實體,還有些情況下只有乙個模型,與自己之間存在多對多關係。比如使用者之間的關注。表示使用者關注其他使用者時,只有使用者乙個實體,沒有 第二個實體。如果關係中的兩側都在同乙個表中,這種關係稱為自引用關係。在關注中,關係的左側是使...
Flask 資料庫高階多對多關係
之前介紹了多對多關係 在之前介紹的多對多關係中,關聯表就是乙個簡單的表,不是模型,sqlalchemy 會自動接管這個表。多對多關係可以分解成原表和關聯表之間的兩個一對多關係。這個表裡面儲存了原表的兩個主鍵作為自己的聯合主鍵。存在的問題 因為在這種關聯表裡操作的時候都是物件導向的,新增,刪除等操作都...
Flask 多對多關係
1.專案結構 對錶的基本操作可見鏈結 3.多對多關係 以下通過文章,作者,文章 標記 三個表示例操作 from flask import flask from flask sqlalchemy import sqlalchemy import config create table article ...