数据迁移

安装
    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 (三) 数据迁移的更多相关文章

  1. codefirst数据迁移技术,在保留数据库数据下实现对模型的修改并映射到数据库

    一前言 这是我的处女作,写的不好的地方还望指出共同讨论.EF的数据访问方式有三种DbFirst,ModelFirst,还有本文要提到的CodeFirst 三者都是以ORM的方式建立.本人之前学习的.n ...

  2. Flask入门之触发器,事件,数据迁移

    SQLAlchemy Core和SQLAlchemy ORM都具有各种各样的事件挂钩: 核心事件 - 这些在 Core Events中描述,并包括特定于连接池生命周期,SQL语句执行,事务生命周期以及 ...

  3. Docker数据卷Volume实现文件共享、数据迁移备份(三)--技术流ken

    前言 前面已经写了两篇关于docker的博文了,在工作中有关docker的基本操作已经基本讲解完了.相信现在大家已经能够熟练配置docker以及使用docker来创建镜像以及容器了.本篇博客将会讲解如 ...

  4. Docker数据卷Volume实现文件共享、数据迁移备份(三)

    数据卷volume功能特性 数据卷 是一个可供一个或多个容器使用的特殊目录,实现让容器中的一个目录和宿主机中的一个文件或者目录进行绑定.数据卷 是被设计用来持久化数据的对于数据卷你可以理解为NFS中的 ...

  5. 生产环境下,oracle不同用户间的数据迁移。第三部分

    任务名称:生产环境下schema ELON数据迁移至schema TIAN########################################前期准备:1:确认ELON用户下的对象状态se ...

  6. MySQL数据迁移到SQL Server

    数据迁移的工具有很多,基本SSMA团队已经考虑到其他数据库到SQL Server迁移的需求了,所以已经开发了相关的迁移工具来支持. 此博客主要介绍MySQL到SQL Server数据迁移的工具:SQL ...

  7. 从零自学Hadoop(16):Hive数据导入导出,集群数据迁移上

    阅读目录 序 导入文件到Hive 将其他表的查询结果导入表 动态分区插入 将SQL语句的值插入到表中 模拟数据文件下载 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并 ...

  8. 从零自学Hadoop(17):Hive数据导入导出,集群数据迁移下

    阅读目录 序 将查询的结果写入文件系统 集群数据迁移一 集群数据迁移二 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephis ...

  9. SQL SERVER几种数据迁移/导出导入的实践

    SQLServer提供了多种数据导出导入的工具和方法,在此,分享我实践的经验(只涉及数据库与Excel.数据库与文本文件.数据库与数据库之间的导出导入). (一)数据库与Excel 方法1: 使用数据 ...

随机推荐

  1. Android Weekly Notes Issue #252

    Android Weekly Issue #252 April 9th, 2017 Android Weekly Issue #252. 本期内容: 变化的渐变背景实现; Kotlin 1.1特性; ...

  2. 科目三靠边停车难度升级,超过50cm不合格怎么破?

    驾考新规实施了几天,考过的学员普遍反映科目三难度升级,其中靠边停车项目的扣分点细化之后,一不小心就会不合格.新规以前靠边停车不压线就好了,新规之后,车辆距离马路右侧边缘线超过50cm就要扣100分,对 ...

  3. js中的命名空间

    尽量不要使用全局变量,防止环境污染和命名冲突. 所以,将全局变量放在一个命名空间下,是一个好的解决方案. 静态命名空间 1. 直接赋值 这是最基本的方法,但是它很啰嗦,你得重复书写多次变量名.好处是它 ...

  4. hdu-5621 KK's Point(dp+数学)

    题目链接: KK's Point Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Others ...

  5. android手机各大分区详解

    1. bootloader  当我们拿到一款手机,第一件事应该就是按下电源键开机,那么从开机到进入到桌面程序这中间发生了些什么呢,我们从下面这张简化了的手机结构图开始: 注意:该结构图并不反映手机的实 ...

  6. springboot开启远程调试

    远程调试maven设置 The run goal forks a process for the boot application. It is possible to specify jvm arg ...

  7. 六、mysql语法

    1.条件查询 条件查询需要用到where语句,where必须放到from语句表的后面 执行顺序:先from后where过滤后再检索出来 2.数据排序,asc(升序),desc(降序)默认情况下是asc ...

  8. 深度学习之Batch归一化

    前言            以下内容是个人学习之后的感悟,转载请注明出处~ Batch归一化 在神经网络中,我们常常会遇到梯度消失的情况,比如下图中的sigmod激活函数,当离零点很远时,梯度基本为0 ...

  9. activeMQ:java消息机制初试(一)

    前言:自打学习编程以来,就知道activeMQ这么个东西,但是仅仅限于只知其名,不闻其详.现在加入到新的项目组,项目中使用了这个.现在想重新去学习和了解.最后整合成一个完成的demo,在网上看的Dem ...

  10. 爬虫库之BeautifulSoup学习(一)

    Beautiful Soup的简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据. 官方解释如下: Beautiful Soup提供一些简单的.pytho ...