记一次flask-SQLAlchemy学习的精要部分
模型部分:
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True,autoincrement=False)
username = db.Column(db.String(255))
posts = db.relationship('Posts', backref='user', lazy='dynamic')
def __repr__(self):
return '<id:{0},user:{1}>'.format(self.id,self.username)
__str__ = __repr__
class Posts(db.Model):
__tablename__='posts'
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
title = db.Column(db.String(255))
user_id = db.Column(db.Integer,db.ForeignKey('users.id'))
publish_time=db.Column(db.DateTime)
def __str__(self):
return '<post{1}\'s title:{0}>'.format(self.title,self.id)
__repr__=__str__
使用部分
- 用backref,反向引用
from flask_orm.model import db, Role, User, Posts
import datetime
user = User.query.first()
post1 = Posts(title='Title1', publish_time=datetime.datetime.now())
post2 = Posts(title='Title2', publish_time=datetime.datetime.now())
post3 = Posts(title='Title3', publish_time=datetime.datetime.now())
post1.user = user
post2.user = user
db.session.add_all([post1, post2, post3])
db.session.commit()
print(user.posts.all())
posts = db.relationship('Posts', backref='user', lazy='dynamic')
之前一直对这句话不理解,relationship是关系两个表的,下面给出我的理解
最终效果图
posts
posts是一个User实例的属性,对于一个 User 类的实例,其 posts 属性将返回与User实例相关联的post组成的列表,在此例子中的结果如下:
[<post1's title:Title1>, <post2's title:Title2>]
表的内容为:
post1和post2的user_id全部参照的它user = User.query.first()
,所以posts返回了一个列表,列表的值为和它相关联的posts表中的那部分
backref
backref我的理解是反向引用,虽然在User中声明的,但是却在Posts类的实例中绑定了一个属性user,通过它来访问Users的模型。之后,便能自动的读取到参照的列的值。效果如下
[<post1's title:Title1>, <post2's title:Title2>]
<id:1,user:XiaoXin>
一句话概括一下便是,通过作者能看到所有的文章(posts属性),通过文章能看到作者是谁(backref)反向引用.
Dynamic
print(user.posts)
dynamic的作用来自于这行,我们通过这行来获取与这个user相关的所有posts文章。实际上隐含的查询会调用 all() 返回一个用户列表。 query 对象是隐藏的,因此无法指定更精确的查询过滤器,所以我们可以使用lazy=dynamic,不让它自动执行。加上去之后我们再次输出
print(user.posts)
得到这样的结果
SELECT posts.id AS posts_id, posts.title AS posts_title, posts.user_id AS posts_user_id, posts.publish_time AS posts_publish_time
FROM posts
WHERE %(param_1)s = posts.user_id
变成了sql语句了,我们加上all()这个查询函数
print(user.posts.all())
结果:
[<post1's title:Title1>, <post2's title:Title2>]
- 用user的posts属性返回的列表直接添加。
post4 = Posts(title='Title1', publish_time=datetime.datetime.now())
post5 = Posts(title='Title2', publish_time=datetime.datetime.now())
post6 = Posts(title='Title3', publish_time=datetime.datetime.now())
user.posts.append(post4)
user.posts.append(post5)
print(user.posts.all())
db.session.commit()
小结
注意:
- dynamic (不加载记录,但提供加载记录的查询)
- backref参数可以让我们通过Post.user**属性**来对User的对象进行读取和修改,这一点会很方便。
- lazy参数指的是如何去加载我们指定的关联对象 。subquery立即处理,速度慢; dynamic指在需要数据的时刻加载,对于数据量大的情形,采用dynamic效果会比较好