Flask-模型操作
创建模型
...
字段类型
类型名 | Python类型 | 说明 |
---|---|---|
Integer | int | 普通整数,一般是32位 |
SmallInteger | int | 取值范围小的整数,一般是16位 |
BigInteger | int 或 long | 不限制精度的整数 |
Float | float | 浮点数 |
Numeric | decimal.Decimal | 定点数 |
String | str | 变长字符串 |
Text | str | 长字符串,对较长或不限长度的字符串做了优化 |
Unicode | unicode | 变长Unicode字符串 |
UnicodeText | unicode | 变长Unicode字符串,对较长或不限长度的字符串做了优化 |
Boolean | bool | 布尔值 |
Date | datetime.date | 日期 |
Time | datetime.time | 时间 |
DateTime | datetime.datetime | 日期和时间 |
Interval | detetime.timedelta | 时间间隔 |
LargeBinary | str | 二进制文件 |
常用约束
选项名 | 说明 |
---|---|
primary_key | |
unique | |
index | |
nullable | |
default |
模型操作
单表操作
增加数据
a、一次增加一条数据:
p = Person()
p.name = '小明'
p.age = 22
try:
db.session.add(p)
db.session.commit()
except:
# 回滚
db.session.rollback()
db.session.flush()
b、一次添加多条数据
persons = []
for i in range(10,30):
p = Person()
p.name = 'baoqiang' + str(i)
p.age = i
persons.append(p)
db.session.add_all(persons)
# 增:
@blue.route('/useradd/')
def uesr_add():
# u = User()
# u.name = 'kum'
# u.age = 22
# db.session.add(u) # 将u对象添加到session中
# db.session.commit() # 同步到数据库中
users = []
for i in range(10,30):
u = User()
u.name = 'bingbing' + str(i)
u.age = i
users.append(u)
try:
db.session.add_all(users)
db.session.commit() # 事务提交
except Exception as e:
db.session.rollback() # 回滚
db.session.flush() # 刷新,清空缓存
return 'fail:' + str(e)
return 'success!'
#删
@blue.route('/userdel/')
def user_del():
u = User.query.first() #查询第一条数据
db.session.delete(u)
db.session.commit()
return 'success!'
#改
@blue.route('/userupdate/')
def user_update():
u = User.query.first()
u.age = 100
db.session.commit()
return 'success!'
查
过滤器
filter() 把过滤器添加到原查询上,返回一个新查询
filter_by() 把等值过滤器添加到原查询上,返回一个新查询
limit() 使用指定的值限制原查询返回的结果数量,返回一个新查询
offset() 偏移原查询返回的结果,返回一个新查询
order_by() 根据指定条件对原查询结果进行排序,返回一个新查询
group_by() 根据指定条件对原查询结果进行分组,返回一个新查询
常用查询
all() 以列表形式返回值查询的所有结果,返回列表
first() 返回查询的第一个结果,如果没有结果,则返回None
first_or_404() 返回查询的第一个结果,如果没有结果,则终止请求,返回404错误响应
get() 返回指定主键对应的行,如果没有对应的行,则返回None
get_or_404() 返回指定主键对应的行,如果没找到指定的主键,则终止请求,返回404错误响应
count() 返回查询结果的数量
paginate() 返回一个Paginate对象,它包含指定范围内的结果
查询属性
contains
startswith
endswith
in_
__gt__
__ge__
__lt__
__le__
逻辑运算
与 and_
filter(and_(条件),条件...)
或 or_
filter(or_(条件),条件...)
非 not_
filter(not_(条件),条件...)
示例:
查询:
persons = Person.query.all()
persons = Person.query.filter(Person.age=>22)
# filter功能比filter.by强大
persons = Person.query.filter(Person.age==22) # filter(类.属性==值)
persons = Person.query.filter_by(age=22) # filter_by(属性=值)
persons = Person.query.filter(Person.age.__lt__(22)) # <
persons = Person.query.filter(Person.age.__le__(22)) # <=
persons = Person.query.filter(Person.age.__gt__(22)) # >
persons = Person.query.filter(Person.age.__ge__(22)) # >=
persons = Person.query.filter(Person.age.startswith('宝'))
persons = Person.query.filter(Person.age.endswith('宝'))
persons = Person.query.filter(Person.age.contains('宝'))
persons = Person.query.filter(Person.age.in_((11,12,22)))
persons = Person.query.filter(Person.age>=20, Person.age<30) # and_
persons = Person.query.filter(and_(Person.age>=20, Person.age<30)) # and_
persons = Person.query.filter(or_(Person.age>=30, Person.age<20)) # or_
persons = Person.query.filter(not_(Person.age<30)) # not_
排序:
persons = Person.query.order_by('age') # 升序
persons = Person.query.order_by(desc('age')) # 降序
分页:
persons = Person.query.limit(5) # 取前5个
persons = person.query.offset(5) # 跳过前5个
# 获取页码page和每页数量num
page = int(request.args.get('page'))
per_page = int(request.args.get('per_page'))
# 手动做分页
persons = Person.query.offset((page - 1) * per_page).limit(per_page)
# 使用paginate做分页
persons = Person.query.paginate(page=page, per_page=per_page, error_out=False).items
paginate对象的属性:
items:返回当前页的内容列表
has_next: 是否还有下一页
has_prev: 是否还有上一页
next(error_out=False): 返回下一页的Pagination对象
prev(error_out=False): 返回上一页的Pagination对象
page: 当前页的页码(从1开始)
pages:总页数
per_page: 每页显示的数量
prev_num: 上一页页码数
next_num: 下一页页码数
query: 返回创建该pagination对象的查询对象
total: 查询返回的记录总数
03-模型进阶
多表关联
一对多
class Grade(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(16))
# 定义班级表的一对多关系,不是字段,Student为学生表模型,backref为反向查找名称
# 建立关联
# 第一个参数:关联的模型名(表)
# 第二个参数:反向引用的名称,grade对象,让student去反过来得到grade对象的名称
# 第三个参数:懒加载
# 这里的students不是字段
students = db.relationship('Student', backref='grade', lazy=True)
class Student(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(16))
age = db.Column(db.Integer, default=1)
# 创建外键,关联到班级表的主键,实现一对多关系,班级表中也要有对应操作
gradeid = db.Column(db.Integer, db.ForeignKey(Grade.id))
查:
# 获取学生的所在班级信息(反向)
stu = Student.query.get(stuid)
grade = stu.stus
# 获取班级的所有学生(正向)
grade = Grade.query.get(gradeid)
students = grade.students
删:
# 获取班级的所有学生(正向)
grade = Grade.query.get(id)
db.session.delete(grade)
db.session.commit()
多对多
用户收藏电影,一个用户可以收藏多部电影,一部电影可以被不同的用户收藏,是一个多对多关系
# 中间表(不是类)
collect = db.Table('collects',
# user_id为表字段名称,user.id为外键表的id
db.Column('user_id',db.Integer, db.ForeignKey('usermodel.id'), primary_key=True),
db.Column('movie_id', db.Integer, db.ForeignKey('moviemodel.id'), primary_key=True)
)
# 将user_id、movie_id同时设置为primary_key,即两个值联合唯一
# 用户表
class UserModel(db.Model):
__tablename__ = 'usermodel'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(30), unique=True)
age = db.Column(db.Integer, default=1)
# 电影表
class MovieModel(db.Model):
__tablename__ = 'movie'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(30))
# 关联
# secondary = collect: 设置中间表
users = db.relationship('UserModel', backref='movies', lazy=True, secondary=collect)
lazy属性:
懒加载,可以延迟在使用关联属性的时候才建立关联
lazy='dynamic': 会返回一个query对象(查询集),可以继续使用其它查询方法:如all().
lazy='select': 首次访问到属性的时候,就会全部加载该属性的数据
lazy='joined': 在对关联的两个表进行join操作,从而获取到所有相关的对象
lazy=True: 返回一个可用的列表对象,同select
查:
# 查询用户收藏的所有电影
user = User.query.get(id)
movies = user.movies
# 查询电影被哪些用户收藏
movie = Movie.query.get(id)
users = movie.users
删:
# 中间表的数据会被级联删除
movie = Movie.query.get(id)
db.session.delete(movie)
db.session.commit()
增:
# 用户收藏电影
user = User.query.get(id)
movie = Movie.query.get(id)
user.movies.append(movie)
db.session.commit()
作业:图书馆项目
创建一个项目,用来说明出版社,书籍和作者的关系。
假定关系: 作者:书籍 => 1:n (一本书由一个作者完成,一个作者可以创作多本书)
出版社:书籍 => n:n (一个出版社可以出版多本书,一本书可以由多个出版社出版)
要求:
1、在书籍的book_index.html中有一个’查看所有书籍‘的超链接按钮,点击进入书籍列表
book_list.html页面。
2、在书籍的book_list.html中显示所有书名,点击书名可以进入书籍详情book_detail.html。
3、在书籍book_detail.html中可以点击该书的作者和出版社,进入作者详情的author_detail.html和
出版社详情的publisher_detail.html页面
# 作者
class Author(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(20), unique=True)
age = db.Column(db.Integer, default=1)
sex = db.Column(db.Boolean, default=True)
email = db.Column(db.String(200))
# 关系
books = db.relationship('Book', backref='my_author', lazy='dynamic')
# 书籍
class Book(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(100), unique=True)
date = db.Column(db.DateTime)
# 1对多,外键
authorid = db.Column(db.Integer, db.ForeignKey(Author.id))
# 中间表(书籍-出版社)
book_publisher = db.Table('book_publisher',
db.Column('book_id', db.Integer, db.ForeignKey('book.id'), primary_key=True),
db.Column('publisher_id', db.Integer, db.ForeignKey('publsher.id'), primary_key=True)
)
# 出版社
class Publisher(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(bd.String(20), unique=True)
address = db.Column(db.String(200))
city = db.Column(db.String(100))
provice = db.Column(db.String(100))
country = db.Column(db.String(100))
website = db.Column(db.String(100))
# 多对多,关联book表
books = db.relationship('Book', backref='publishers',
secondary=book_publisher, lazy='dynamic')
合集:
Python全栈(Flask)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库