数据迁移

安装
    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. hdu 1106 排序 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1106 这个题目一开始以为是水题,就想着用来轻松轻松,谁知道改得我想吐!! 除了discuss 中的数据 ...

  2. codeforces A. Array 解题报告

    题目链接:http://codeforces.com/problemset/problem/300/A 题目意思:给出n个数,将它们分成三批:1.所有数相乘的结果 < 0    2.所有数相乘的 ...

  3. CISCO-配置SSH

    PC直接连在交换机端口上,PC的ip地址是:192.168.1.1/24 在交换机的操作步骤如下: 1.设置交换机管理ip Switch#conf t Switch(config)#int vlan ...

  4. 一些常用的页面js收集

    //正则表达式 验证整数格式function checkInt(tint){ var re=/^[-]{0,1}[1-9]+[0-9]*]*$/; //判断字符串是否为数字 if (re.test(t ...

  5. 火狐浏览器安装VULTR笔记

    1.购买一台vultr服务器, 支持支付宝扫码支付,直接美刀转人民币实时结算:优先选日本的,然后美国的; 购买服务器步骤: Server Location: Tokyo Japan Server Ty ...

  6. Azure REST API (5) 中国Azure EA Portal Billing API

    <Windows Azure Platform 系列文章目录> 本文介绍的是国内由世纪互联运维的Azure China. EA Portal的管理url是:https://ea.azure ...

  7. Ubuntu 16.04使用chrome闪屏

    使用Chrome的时候上端经常出现闪动的情况, 但是速度特别快, 根本无法截图, 感觉特别扎心, 以为自己的电脑出现问题了或者显卡驱动出现问题了, 后来才发现问题, 只需要关闭Chrome的硬件加速就 ...

  8. Redis的小白应用

    在window下测试学习redis 步骤: 1.先下载安装 redis,(conf文件制定配置文件(redis-server.exe  redis.conf ),若不指定则默认), 基本上我是直接点击 ...

  9. Codeforces 1108F MST Unification MST + LCA

    Codeforces 1108F MST + LCA F. MST Unification Description: You are given an undirected weighted conn ...

  10. Codeforces1107E Vasya and Binary String 记忆化dp

    Codeforces1107E 记忆化dp E. Vasya and Binary String Description: Vasya has a string \(s\) of length \(n ...