- 一對(duì)多關(guān)系
- 多對(duì)一關(guān)系
- 多對(duì)多關(guān)系
- 一對(duì)一關(guān)系
一對(duì)多關(guān)系(一個(gè)作者,多篇文章)
## 一對(duì)多關(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)系屬性(一個(gè)集合,可以像列表一樣操作,在關(guān)系的出發(fā)側(cè)定義
## relationship()函數(shù)的第一個(gè)參數(shù)為關(guān)系另一側(cè)的模型名稱(chēng)(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ù)形式為:"表名.字段名"
## 模型類(lèi)對(duì)應(yīng)的表名由Flask-SQLAlchemy生成,默認(rèn)為類(lèi)名稱(chēng)的小寫(xiě)形式,多個(gè)單詞通過(guò)下劃線(xiàn)分隔
author_id = db.Column(db.Integer, db.ForeignKey('author.id')) #
# 外鍵字段(author_id)和關(guān)系屬性(articles)的命名沒(méi)有限制
## 建立關(guān)系可通過(guò)操作關(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ù)庫(kù)記錄添加到會(huì)話(huà)中
>>>db.session.add(hello)
>>>db.session.add(boy)
>>>shansan.articles.append(hello) # 操作關(guān)系屬性
>>>shansan.articles.append(boy)
>>>db.session.commit()
基于一對(duì)多的雙向關(guān)系(bidirectional relationship)
在這里我們希望可以在Book類(lèi)中存在這樣一個(gè)屬性:通過(guò)調(diào)用它可以獲取對(duì)應(yīng)的作者的記錄,這類(lèi)返回單個(gè)值的關(guān)系屬性稱(chēng)為標(biāo)量關(guān)系屬性
# 建立雙向關(guān)系時(shí),關(guān)系兩邊都有關(guān)系函數(shù)
# 在關(guān)系函數(shù)中,我們使用back_populates參數(shù)連接對(duì)方,參數(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ò)集合屬性操作關(guān)系,也可通過(guò)標(biāo)量關(guān)系屬性操作關(guān)系
多對(duì)一關(guān)系(多個(gè)市民都在同一個(gè)城市)
# 外鍵總在多的一側(cè)定義
## 多對(duì)一關(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)
一對(duì)一關(guān)系(國(guó)家和首都)
## 一對(duì)一關(guān)系,將關(guān)系函數(shù)的uselist參數(shù)設(shè)為False,使得集合關(guān)系屬性無(wú)法使用列表語(yǔ)義操作
## 這里使用的是一對(duì)一雙向關(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')
多對(duì)多雙向關(guān)系(老師和學(xué)生)
- 多對(duì)多關(guān)系的建立需要使用關(guān)聯(lián)表(association table)。關(guān)聯(lián)表不存儲(chǔ)數(shù)據(jù),只用來(lái)存儲(chǔ)關(guān)系兩側(cè)模型的外鍵對(duì)應(yīng)關(guān)系
- 定義關(guān)系兩側(cè)的關(guān)系函數(shù)時(shí),需要添加一個(gè)secondary參數(shù),值設(shè)為關(guān)聯(lián)表的名稱(chēng)
- 關(guān)聯(lián)表由使用db.Table類(lèi)定義,傳入的第一個(gè)參數(shù)為關(guān)聯(lián)表的名稱(chēng)
- 我們?cè)陉P(guān)聯(lián)表中將多對(duì)多的關(guān)系分化成了兩個(gè)一對(duì)多的關(guān)系
## 多對(duì)多關(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ù)庫(kù)字段,而是類(lèi)似于特定的查詢(xún)函數(shù)
- 當(dāng)關(guān)系屬性被調(diào)用時(shí),關(guān)系函數(shù)會(huì)加載相應(yīng)的記錄


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