一对多:
以作者和文章来简述:一个作者可以有多篇文章,一个文章只能有一个作者,以下是初始代码
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)
class Author(db.Model):
"""作者模型"""
# db.Column声明这是一个列,会在数据表中创建,primary_key声明这是一个主键
id = db.Column(db.Integer, primary_key=True)
# db.String必须传入一个最大长度,unique声明这个字段不能出现重复值
name = db.Column(db.String(20), unique=True)
phone = db.Column(db.String(20))
class Article(db.Model):
"""文章模型"""
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(50), index=True)
body = db.Column(db.Text)
# 创建一个author_id的外键字段,
# db.ForeignKey中第一个参数是对应的表名.主键字段名
author_id = db.Column(db.Integer, db.ForeignKey('author.id'))
1.定义外键
定义关系的第一步是创建外键。外键是(foreignkey)用来在A表存储B表的主键值以便和B表建立联系的关系字段。因为外键只能存储单一数据(标量)所以外键总是在“多”这一侧定义,多篇文章属于同一个作者,所以我们需要为每篇文章添加外键存储作者的主键值以指向对应的作者。在Article模型中,我们定义一个author_id字段作为外键:
class Article(db.Model):
"""文章模型"""
# ......
# 创建一个author_id的外键字段,
# db.ForeignKey中第一个参数是对应的表名.主键字段名组成的字符串
author_id = db.Column(db.Integer, db.ForeignKey('author.id'))
提示:键字段的命名没有限制,因为要连接的目标是auther表的id,所以为了便于区分而将这个外键字段的名称命名为author_id。
注意:传入ForeignKey类的参数author.id,其中author指的是Author模型对应的表名称,而id指的是字段名,即“表名.字段名”。模型类对应的表名由Flask-SQLlchemy生成,默认为类名称的小写形式,多个单词通过下划线分隔,你也可以显式地通过
__tablename__
属性自己指定,后面不再提示。
2.定义关系属性
定义关系的第二步是使用关系函数定义关系属性。关系属性在关系的出发侧定义,即一对多关系的“一”这一侧。一个作者拥有多篇文章,在Author模型中,我们定义了一个articles属性来表示对应的多篇文章:
class Author(db.Model):
# ......
articles = db.relationship('Article') # collection
关系属性的名称没有限制,你可以自由修改。它相当于一个快捷查询,不会作为字段写入数据库中。
这个属性并没有使用Column类声明为列,而是使用了db.relationship()关系函数定义为关系属性,因为这个关系属性返回多个记录,我们称之为集合关系属性。relationship()函数的第一个参数为关系另一侧的模型名称,它会告诉SQLAlchemy将Author类与Article类建立关系。当这个关系属性被调用时,SQLAlchemy会找到关系另一侧(即article表)的外键字段(即author_ id),然后反向查询article表中所有author_id值为当前表主键值(即author.id)的记录,返回包含这些记录的列表,也就是返回某个作者对应的多篇文章记录。