一对多关系
下面的一对多关系以作者和文章为例:
首先创建一个文章表:
class Post(db.Model):
id = db.Column(db.Integer(),primary_key=True)
title = db.Column(db.String(255))
text = db.Column(db.Text())
publish_date = db.Column(db.DateTime())
user_id = db.Column(db.Integer(),db.ForeignKey('user.id'))
此处注意:
- 传给db.ForeignKey的参数,是一个用来代表user表id列的字符串,如果user表中用__tablename__自定义表名,则需要用自定义的表名
- “多”的一方写ForeignKey,可以通过表名.(“一”的一方的backref)对“一”的一方进行读取和修改。relationship可以在任意一方,一般是在“一”的一方。
下面创建作者表:
class User(db.Model):
id = db.Column(db.Integer(),primary_key=True)
username = db.Column(db.String(255))
password = db.Column(db.String(255))
posts = db.relationship('Post',backref='user',lazy='dynamic')
可以发现一对多关系的创建和上文总结的一对一关系只有一个区别:
把uselist = False,替换为了lazy = 'dynamic’
lazy关键字的作用
官方解释:lazy 决定了 SQLAlchemy 什么时候从数据库中加载数据
查阅资料发现lazy其实有五个可选参数,分别是“dynamic”,“select”, “joined”,“subquery"和不常用的"noload”, 一般只用前三个,默认值为“select”。
registrations = db.Table('registrations',
db.Column('student_id', db.Integer, db.ForeignKey('students.id')),
db.Column('class_id', db.Integer, db.ForeignKey('classes.id')))
class Student(db.Model):
__tablename__ = 'students'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64))
class_id = db.Column(db.Integer, db.ForeignKey('classes.id'))
def __repr__(self):
return '<Student: %r>' %self.name
class Class(db.Model):
__tablename__ = 'classes'
id = db.Column(db.Integer, primary_key=True)
students = db.relationship('Student', backref='_class', lazy="dynamic")
name = db.Column(db.String(64))
def __repr__(self):
return '<Class: %r>' %self.name
示例
可以看到, 执行c1.student返回的是是一个 query对象,而select或者是joined都会直接返回结果,在数据量较大时不适用。而多对一和一对一的关系中不使用lazy = ‘dynamic’,因为返回结果只有一个,没有必要延迟加载数据。
当然,也可以给多对多关系中反向引用backref中添加lazy属性
backref = db.backref('students', lazy='dynamic')
即可