- 一對多關(guān)系
- 多對一關(guān)系
- 多對多關(guān)系
- 一對一關(guān)系
一對多關(guān)系(一個作者,多篇文章)
## 一對多關(guān)系,單作者-多文章,外鍵不可少
## 外鍵(ForeignKey)總在多的那邊定義,關(guān)系(relationship)總在單的那邊定義
class Author(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(70), unique=True)
phone = db.Column(db.String(20))
# articles為關(guān)系屬性(一個集合,可以像列表一樣操作,在關(guān)系的出發(fā)側(cè)定義
## relationship()函數(shù)的第一個參數(shù)為關(guān)系另一側(cè)的模型名稱(Article)
articles = db.relationship('Article')
class Article(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(15), index=True)
body = db.Column(db.Text)
# 傳入ForeignKey的參數(shù)形式為:"表名.字段名"
## 模型類對應(yīng)的表名由Flask-SQLAlchemy生成,默認(rèn)為類名稱的小寫形式,多個單詞通過下劃線分隔
author_id = db.Column(db.Integer, db.ForeignKey('author.id')) #
# 外鍵字段(author_id)和關(guān)系屬性(articles)的命名沒有限制
## 建立關(guān)系可通過操作關(guān)系屬性進(jìn)行
>>>shansan = Author(name="shansan")
>>>hello = Article(title="Hello world !")
>>>boy = Article(title="Hello Boy !")
>>>db.session.add(shansan) # 將創(chuàng)建的數(shù)據(jù)庫記錄添加到會話中
>>>db.session.add(hello)
>>>db.session.add(boy)
>>>shansan.articles.append(hello) # 操作關(guān)系屬性
>>>shansan.articles.append(boy)
>>>db.session.commit()
基于一對多的雙向關(guān)系(bidirectional relationship)
在這里我們希望可以在Book類中存在這樣一個屬性:通過調(diào)用它可以獲取對應(yīng)的作者的記錄,這類返回單個值的關(guān)系屬性稱為標(biāo)量關(guān)系屬性
# 建立雙向關(guān)系時,關(guān)系兩邊都有關(guān)系函數(shù)
# 在關(guān)系函數(shù)中,我們使用back_populates參數(shù)連接對方,參數(shù)的值設(shè)置為關(guān)系另一側(cè)的關(guān)系屬性名
class Writer(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
# back_populates的參數(shù)值為關(guān)系另一側(cè)的關(guān)系屬性名
books = db.relationship('Book', back_populates='writer')
def __repr__(self):
return '<Writer %r>' % self.name
class Book(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), index=True)
writer_id = db.Column(db.Integer, db.ForeignKey('writer.id'))
writer = db.relationship('Writer', back_populates='books')
def __repr__(self):
return '<Book %r>' % self.name
# 設(shè)置雙向?qū)傩院?,我們既可以通過集合屬性操作關(guān)系,也可通過標(biāo)量關(guān)系屬性操作關(guān)系
多對一關(guān)系(多個市民都在同一個城市)
# 外鍵總在多的一側(cè)定義
## 多對一關(guān)系中,外鍵和關(guān)系屬性都在多的一側(cè)定義
## 這里的關(guān)系屬性是標(biāo)量關(guān)系屬性(返回單一數(shù)據(jù))
class Citizen(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20), unique=True)
city_id = db.Column(db.Integer, db.ForeignKey('city.id'))
city = db.relationship('City')
class City(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20), unique=True)
一對一關(guān)系(國家和首都)
## 一對一關(guān)系,將關(guān)系函數(shù)的uselist參數(shù)設(shè)為False,使得集合關(guān)系屬性無法使用列表語義操作
## 這里使用的是一對一雙向關(guān)系
class Country(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20), unique=True)
capital = db.relationship('Capital', uselist=False)
class Capital(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20), unique=True)
country_id= db.Column(db.Integer, db.ForeignKey('country.id'))
country = db.relationship('Country')
多對多雙向關(guān)系(老師和學(xué)生)
- 多對多關(guān)系的建立需要使用關(guān)聯(lián)表(association table)。關(guān)聯(lián)表不存儲數(shù)據(jù),只用來存儲關(guān)系兩側(cè)模型的外鍵對應(yīng)關(guān)系
- 定義關(guān)系兩側(cè)的關(guān)系函數(shù)時,需要添加一個secondary參數(shù),值設(shè)為關(guān)聯(lián)表的名稱
- 關(guān)聯(lián)表由使用db.Table類定義,傳入的第一個參數(shù)為關(guān)聯(lián)表的名稱
- 我們在關(guān)聯(lián)表中將多對多的關(guān)系分化成了兩個一對多的關(guān)系
## 多對多關(guān)系,使用關(guān)聯(lián)表(association table),關(guān)聯(lián)表由db.Table定義
## 關(guān)系函數(shù)需要設(shè)置secondary參數(shù),值為關(guān)系表名
association_table = db.Table('association_table',
db.Column('student_id', db.Integer, db.ForeignKey('teacher.id')),
db.Column('teacher_id', db.Integer, db.ForeignKey('student.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')
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))
students = db.relationship('Student', secondary=association_table, back_populates='teachers')
常用的SQLAlchemy關(guān)系函數(shù)參數(shù)和常用的SQLAlchemy關(guān)系記錄加載方式(lazy參數(shù)可選值)
- 使用關(guān)系函數(shù)定義的屬性不是數(shù)據(jù)庫字段,而是類似于特定的查詢函數(shù)
- 當(dāng)關(guān)系屬性被調(diào)用時,關(guān)系函數(shù)會加載相應(yīng)的記錄


相關(guān)
http://www./
https://github.com/sqlalchemy/sqlalchemy
https://github.com/mitsuhiko/flask-sqlalchemy
來源:http://www./content-2-144151.html
|