Flask (三) 数据迁移
数据迁移
安装
pip install flask-migrate
初始化
使用app和db进行migrate对象初始化
from flask_migrate import Migrate
migrate = Migrate()
migrate.init_app(app=app, db=db)
安装了flask-script后,可以在manager上添加迁移指令
from flask_migrate import MigrateCommand
manager.add_command('db', MigrateCommand)
操作
python manager.py db init 只调用一次, 这里的db是添加命令时给定的名称
python manager.py db migrate 生成迁移文件
python manager.py db upgrade 执行迁移中的升级
python manager.py db downgrade 执行迁移中的降级
模型进阶
创建模型
# 模型:类
class Person(db.Model):
__tablename__ = 'person'
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)
字段类型
类型名 | 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 | datetime.timedelta | 时间间隔 |
LargeBinary | str | 二进制文件 |
常用约束
选项名 | 说 明 |
---|---|
primary_key | 如果设为 True ,这列就是表的主键 |
unique | 如果设为 True ,这列不允许出现重复的值 |
index | 如果设为 True ,为这列创建索引,提升查询效率 |
nullable | 如果设为 True ,这列允许使用空值;如果设为 False ,这列不允许使用空值 |
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 = '宝强' + str(i)
p.age = i
persons.append(p)
db.session.add_all(persons)
db.session.commit()
删除数据
p = Person.query.first() # 获取第一条数据
db.session.delete(p)
db.session.commit()
修改数据
p = Person.query.first()
p.age = 100
db.session.commit()
查询数据
过滤器
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])) # in_
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.limit(5) # 取前5个
persons = Person.query.order_by('age') # 升序
persons = Person.query.order_by('-age') # 降序
persons = Person.query.order_by(desc('age')) # 降序
persons = Person.query.offset(5) # 跳过前5个
分页:
# 获取页码page和每页数量num
page = int(request.args.get('page'))
num = int(request.args.get('num'))
# 手动做分页
persons = Person.query.offset((page-1) * num).limit(num)
# 使用paginate做分页
persons = Person.query.paginate(page, num, 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:查询返回的记录总数
多表关联
一对多
# 一对多
class Grade(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(16))
# 定义班级标的一对多关系,不是字段, Student为学生表模型, backref为反向查找名称
students = db.relationship('Student', backref='grade1', 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)
# 创建外键,关联到班级表的主键,实现一对多关系,班级表中也要有对应操作
grade = 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字段会变为null
grade = Grade.query.get(id)
db.session.delete(grade)
db.session.commit()
多对多
用户收藏电影,一个用户可以收藏多部电影, 一部电影可以被不同的用户收藏, 是一个多对多关系.
# 中间表(不是模型)
collects = db.Table('collects',
# user_id为表字段名称, user.id为外键表的id
db.Column('user_id', db.Integer, db.ForeignKey('user.id'), primary_key=True),
db.Column('movie_id', db.Integer, db.ForeignKey('movie.id'), primary_key=True)
)
class Movie(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(200))
class User(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)
# 多对多 关联的学生表格的模型, 中间表的名称, 反向查找
movies = db.relationship('Movie', backref='users', secondary=collects, lazy='dynamic')
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()
Flask (三) 数据迁移的更多相关文章
- codefirst数据迁移技术,在保留数据库数据下实现对模型的修改并映射到数据库
一前言 这是我的处女作,写的不好的地方还望指出共同讨论.EF的数据访问方式有三种DbFirst,ModelFirst,还有本文要提到的CodeFirst 三者都是以ORM的方式建立.本人之前学习的.n ...
- Flask入门之触发器,事件,数据迁移
SQLAlchemy Core和SQLAlchemy ORM都具有各种各样的事件挂钩: 核心事件 - 这些在 Core Events中描述,并包括特定于连接池生命周期,SQL语句执行,事务生命周期以及 ...
- Docker数据卷Volume实现文件共享、数据迁移备份(三)--技术流ken
前言 前面已经写了两篇关于docker的博文了,在工作中有关docker的基本操作已经基本讲解完了.相信现在大家已经能够熟练配置docker以及使用docker来创建镜像以及容器了.本篇博客将会讲解如 ...
- Docker数据卷Volume实现文件共享、数据迁移备份(三)
数据卷volume功能特性 数据卷 是一个可供一个或多个容器使用的特殊目录,实现让容器中的一个目录和宿主机中的一个文件或者目录进行绑定.数据卷 是被设计用来持久化数据的对于数据卷你可以理解为NFS中的 ...
- 生产环境下,oracle不同用户间的数据迁移。第三部分
任务名称:生产环境下schema ELON数据迁移至schema TIAN########################################前期准备:1:确认ELON用户下的对象状态se ...
- MySQL数据迁移到SQL Server
数据迁移的工具有很多,基本SSMA团队已经考虑到其他数据库到SQL Server迁移的需求了,所以已经开发了相关的迁移工具来支持. 此博客主要介绍MySQL到SQL Server数据迁移的工具:SQL ...
- 从零自学Hadoop(16):Hive数据导入导出,集群数据迁移上
阅读目录 序 导入文件到Hive 将其他表的查询结果导入表 动态分区插入 将SQL语句的值插入到表中 模拟数据文件下载 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并 ...
- 从零自学Hadoop(17):Hive数据导入导出,集群数据迁移下
阅读目录 序 将查询的结果写入文件系统 集群数据迁移一 集群数据迁移二 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephis ...
- SQL SERVER几种数据迁移/导出导入的实践
SQLServer提供了多种数据导出导入的工具和方法,在此,分享我实践的经验(只涉及数据库与Excel.数据库与文本文件.数据库与数据库之间的导出导入). (一)数据库与Excel 方法1: 使用数据 ...
随机推荐
- git项目.gitignore文件不生效解决办法
配置好.gitignore文件如下: HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .clas ...
- windows64位安装mysql-5.7.12,图文
linux下安装mysql教程一大片,我就不说了,再此说下windows 下如何安装这个5.7版本,并且有些坑已踩! 一:进入mysql下载地址:http://www.mysql.com/downlo ...
- LightOJ1220 —— 质因数分解
题目链接:https://vjudge.net/problem/LightOJ-1220 1220 - Mysterious Bacteria PDF (English) Statistics ...
- HDU5968 异或密码 —— 二分 + 边界的细节处理
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5968 异或密码 Time Limit: 2000/1000 MS (Java/Others) M ...
- TensorFlow 图像预处理(一) 图像编解码,图像尺寸调整
from: https://blog.csdn.net/chaipp0607/article/details/73029923 TensorFlow提供了几类图像处理函数,下面介绍图像的编码与解码,图 ...
- 在SQL SERVER 2008中通过已有的数据库生成建库脚本
- 微信小程序自定义下导航页面切换效果的合理写法
上图::: 导航模板内容页面的定义: <template name="naviBot"> <view class='navwrap t_cen font_26 ...
- SPOJ:Another Longest Increasing Subsequence Problem(CDQ分治求三维偏序)
Given a sequence of N pairs of integers, find the length of the longest increasing subsequence of it ...
- BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP
BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP Description In an effort to better manage t ...
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源方法
一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...