数据模型

数据库回顾

  • 分类:

    • 关系型数据库:MySQL、sqlite、…
    • 非关系型数据库:Redis、MongoDB、…
  • 操作:
    • 执行原生SQL语句,每次都需要拼接SQL语句,非常繁琐而且特别容易出错。
    • ORM(对象关系映射),使用ORM可以通过对对象的操作完成对数据库的操作。

flask-sqlalchemy

  • 说明:其实是sqlalchemy扩展库在flask中的移植库,通过了绝大多数关系型数据库的支持(ORM)

  • 安装:pip install flask-sqlalchemy

  • 连接地址配置:

    • 名称:SQLALCHEMY_DATABASE_URI
    • 格式:
      • sqlite:sqlite:/// + 数据库文件名
      • MySQL:数据库名+驱动名://用户名:密码@主机:端口/数据库
  • 使用:

    # 配置数据连接地址
    base_dir = os.path.dirname(__file__)
    database_uri = 'sqlite:///' + os.path.join(base_dir, 'data.sqlite')
    app.config['SQLALCHEMY_DATABASE_URI'] = database_uri
    # 禁止数据的修改追踪(需要消耗资源)
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 创建数据库操作对象
    db = SQLAlchemy(app) # 设计模型类
    class User(db.Model):
    # 表名默认会将模型名转为小写加下划线的形式
    # 如:UserModel => user_model
    # 指定表名
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), unique=True)
    email = db.Column(db.String(32), unique=True)
  • 数据表操作

    @app.route('/create/')
    def create():
    # 创建数据表
    db.create_all()
    return '数据表已创建' @app.route('/drop/')
    def drop():
    db.drop_all()
    return '数据表已删除' # 添加终端命令,完成数据表的创建
    @manager.command
    def createall():
    # 先删除原来的,副作用很大
    db.drop_all()
    # 然后再创建
    db.create_all()
    return '数据表已创建' # 添加终端命令,完成数据表的删除
    @manager.command
    def dropall():
    if prompt_bool('您确定要删库跑路吗?'):
    db.drop_all()
    return '数据表已删除'
    return '删库有风险,操作需谨慎!'

    执行终端命令:python manage.py createall,即可创建数据表

数据库迁移

  • 说明:将数据模型的更改应用到数据表的操作叫数据库迁移。flask-migrate就是专门做迁移的扩展库。

  • 安装:pip install flask-migrate

  • 使用:

    from flask_migrate import Migrate
    
    # 创建数据库迁移对象
    migrate = Migrate(app, db) # 将迁移命令添加到终端
    manager.add_command('db', MigrateCommand)
  • 迁移:

    • 初始化,只需要一次,创建用户存放迁移脚本的目录及相关文件。
    python manage.py db init
    • 根据数据模型与数据表,生成迁移脚本。
    python manage.py db migrate
    • 执行迁移脚本
    python manage.py db upgrade
  • 提示:

    • 初始化操作只需要一次,以后生成迁移脚本与执行迁移脚本循环执行即可完成数据库的迁移。
    • 不是每次迁移都会成功,迁移出错时需要手动解决。

CURD操作

  • 增加数据

    # 设置自动提交操作,请求结束时无论如何都会提交
    app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True # 增加数据
    @app.route('/insert/')
    def insert():
    # 创建对象
    # jie = User(name='八戒', email='bajie@163.com', age=30)
    # hou = User(name='猴哥', email='houge@163.com', age=20)
    # 保存到数据库,只能保存一条数据
    # db.session.add(hou) bei = User(name='贝贝', email='bei@163.com', age=28)
    jing = User(name='晶晶', email='jing@163.com', age=18)
    huan = User(name='欢欢', email='huan@163.com', age=22)
    ying = User(name='迎迎', email='ying@163.com', age=23)
    ni = User(name='妮妮',email='ni@163.com',
    age=20) # 保存到数据库,一次性保存多条数据
    db.session.add_all([bei, jing, huan, ying, ni]) # 提交操作,若没有设置自动提交,每次执行操作都需要手动提交一次
    # db.session.commit() return '数据已添加'
  • 查询数据

    # 查询操作
    @app.route('/select/<uid>/')
    def select(uid):
    # 根据主键进行查询,找到返回对象,没找到返回None
    user = User.query.get(uid)
    if user:
    return user.name
    return '查无此人'
  • 修改数据

    # 修改数据
    @app.route('/update/<uid>/')
    def update(uid):
    user = User.query.get(uid)
    if user:
    user.email = 'xxx@163.com'
    # 再次添加到数据库即可
    db.session.add(user)
    return '数据已修改'
    return '查无此人'
  • 删除数据

    # 删除数据
    @app.route('/delete/<uid>/')
    def delete(uid):
    user = User.query.get(uid)
    if user:
    db.session.delete(user)
    return '数据已删除'
    return '查无此人'

模型设计参考

  • 常见的字段类型

    字段类型 python类型 说明
    Integer int 整型(32)
    SmallInteger int 整型(16)
    BigInteger int/long 整型(64)
    Float float 浮点型
    String str 变长字符串
    Text str 不受限制的文本
    Boolean bool 布尔值,True/False
    Date datetime.date 日期
    Time datetime.time 时间
    DateTime datetime.datetime 日期时间
    Interval datetime.timedelta 时间间隔
    PickleType pickle.dumps() 使用pickle模块序列化后的python对象
    LargeBinary bytes 任意大的二进制数据
  • 常见字段选项

    选项 说明
    primary_key 是否作为主键索引,默认为False
    autoincrement 是否设置字段自增,默认为False
    unique 是否作为唯一索引,默认为False
    index 是否作为普通索引,默认为False
    nullable 字段是否可以为空,默认为True
    default 设置默认值
  • 总结:

    • 插入数据可以不传值的情况:自增的字段、可以为空的字段、有默认值的字段
    • 使用flask-sqlalchemy时每个模型都需要有一个主键,通常主键字段名称为id
    • 数据模型类名与数据表中的名字
      • 默认:会将模型名转换为小写加下划线的方式,如:UserModel => user_model
      • 指定:通过类属性__tablename__指定表名

各种查询

  • 说明:在数据库的操作中,绝大多数都是查询操作,而且这些操作都是通过方法来实现的。

  • 常见操作:

    操作 说明
    get 根据主键查询,查到返回对象,没查到返回None
    get_or_404 根据主键查询,查到返回对象,没查到报404错
    first 返回第一条数据,没有时返回None
    first_or_404 返回第一条数据,没有时报404错
    all 查询所有数据组成的列表
    limit 限制结果集数量,返回时查询对象
    offset 结果集偏移数量,返回时查询对象
    order_by 排序,指定字段后,默认按升序排序(asc),降序(desc),可以指定多个字段
    count 统计个数
  • 聚合函数:max、min、sum、avg、count

    from sqlalchemy import func
    
    @app.route('/query/')
    def query():
    # 聚合函数
    # max_age = db.session.query(func.max(User.age)).scalar()
    max_age = db.session.query(func.min(User.age)).scalar()
    return str(max_age)
  • 指定条件查询

    @app.route('/query/')
    def query():
    # 指定等值条件
    # users = User.query.filter_by(age=18).all()
    # 指定任意条件
    users = User.query.filter(User.age > 18).all()
    return ','.join(u.name for u in users)

filter条件查询

  • 关系

    >, __gt__:大于
    示例: # users = User.query.filter(User.age > 20).all()
    # 等价于上式
    users = User.query.filter(User.age.__gt__(20)).all()
    >=,__ge__:大于等于
    <, __lt__:小于
    <=,__le__:小于等于
    ==,__eq__:等于
    !=,__ne__:不等于
  • 范围

    users = User.query.filter(User.id.between(1, 3)).all()
    users = User.query.filter(User.id.in_((1, 3, 5))).all()
    users = User.query.filter(User.id.notin_((1, 3, 5))).all()
  • 内容

    # 包含指定内容
    # users = User.query.filter(User.email.contains('ng')).all()
    # 以指定内容开头
    # users = User.query.filter(User.email.startswith('fe')).all()
    # 以指定内容结尾
    # users = User.query.filter(User.email.endswith('.com')).all()
    # 模糊匹配
    # users = User.query.filter(User.email.like('l%')).all()
    users = User.query.filter(User.email.notlike('l%')).all()
  • 逻辑

    from sqlalchemy import and_, or_
    
    # 默认的关系就是逻辑与
    # users = User.query.filter(User.id > 3, User.age > 20).all()
    # 与上式等价
    # users = User.query.filter(and_(User.id > 3, User.age > 20)).all()
    # 逻辑或
    users = User.query.filter(or_(User.id > 3, User.age > 20)).all()

Flask—05-理解掌握flask数据模型(01)的更多相关文章

  1. Flask 框架理解(一)

    Flask 框架理解(一) web 服务器 , web 框架 以及 WSGI 这里说的 web 服务器特指纯粹的 python HTTP 服务器(比如 Gunicorn,而不是 Apache,Ngin ...

  2. python 全栈开发,Day142(flask标准目录结构, flask使用SQLAlchemy,flask离线脚本,flask多app应用,flask-script,flask-migrate,pipreqs)

    昨日内容回顾 1. 简述flask上下文管理 - threading.local - 偏函数 - 栈 2. 原生SQL和ORM有什么优缺点? 开发效率: ORM > 原生SQL 执行效率: 原生 ...

  3. Flask最强攻略 - 跟DragonFire学Flask - 第六篇 Flask 中内置的 Session

    Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from ...

  4. Flask最强攻略 - 跟DragonFire学Flask - 第四篇 Flask 中的模板语言 Jinja2 及 render_template 的深度用法

    是时候开始写个前端了,Flask中默认的模板语言是Jinja2 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符 ...

  5. 使用Flask+uwsgi+Nginx部署Flask正式环境

    环境准备 在开始正式讲解之前,我们将首先进行环境准备. Step1:安装Python,pip以及nginx: sudo apt-get update sudo apt-get install pyth ...

  6. Flask 入门一( flask 框架和 flask-script 库)

    Flask 入门一( flask 框架 和 flask-script 库) 一.Flask框架: 1.简介 Flask是一个非常小的Python Web框架,被称为微型框架:只提供了一个稳健的核心,其 ...

  7. 初识Flask框架,以及Flask中的模板语言jinjia2和Flask内置的Session

    一.web框架的对比 首先我们先来看下比较火的web框架 1.Django: 优点:大而全,所有组件都是组织内部开发高度定制化,教科书级别的框架 缺点:大到浪费资源,请求的时候需要的资源较高 2.Fl ...

  8. Flask(3)- flask中的CBV、werkzeug+上下文初步解读、偏函数和线程安全

    一.flask中的CBV 对比django中的CBV,我们来看一下flask中的CBV怎么实现? from flask import Flask, render_template, url_for, ...

  9. 第七篇 Flask实例化配置及Flask对象配置

    一.Flask对象的配置 Flask 是一个非常灵活且短小精干的web框架 , 那么灵活性从什么地方体现呢? 有一个神奇的东西叫 Flask配置 , 这个东西怎么用呢? 它能给我们带来怎么样的方便呢? ...

  10. flask 第六篇 flask内置的session

    Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from ...

随机推荐

  1. 项目搭建系列之二:SpringMVC框架下配置MyBatis

    1.什么是MyBatis? MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis ...

  2. git stash压栈

    git stash 用于暂存当前正在进行的工作,如想pull最新的代码,又不想加新的commit,或者为了fix一个紧急的bug,先stash,返回到自己上一个commit. 修改完bug后,再执行g ...

  3. 关于c3p0连接池连接mysql数据库需要注意的几点

    什么是数据库连接池: 用池来管理Connection,这可以重复使用Connection.有了池,所以我们就不用自己来创建Connection,而是通过池来获取Connection对象. 当使用完Co ...

  4. 利用函数回调获取setInterval中返回的值

    我们都知道,定时器里面想返回值如果你用return根本没作用,那么怎么拿到定时器所返回的值呢, 现在只需要利用回调函数,给主函数传一个函数类型的参数callback,然后把想要返回的num再传给cal ...

  5. 深度语义匹配模型-DSSM 及其变种

    转自:http://ju.outofmemory.cn/entry/316660 感谢分享~ DSSM这篇paper发表在cikm2013,短小但是精炼,值得记录一下 ps:后来跟了几篇dssm的pa ...

  6. uwsgi特性

    uwsgi 特性 官网参考 X-Sendfile仿真 即使前端 代理/webserver 不支持X-Sendfile (或者不能访问静态资源),可以使用 uwsgi 内部的 offloading 来模 ...

  7. sql developer中英文切换

    今天使用oracle sql developer时做调优建议时找到的建议显示为?的乱码,本人sql developer为中文版,修改为英文版后问题解决. 查看帮助菜单中的属性选项卡,user.lang ...

  8. March 11 2017 Week 10 Saturday

    Wisdom outweighs any wealth. 智慧比财富更有价值. Wisdom can create wealth if used in proper ways, it can help ...

  9. vim编辑下几个退出保存的命令

    :w 将数据写入硬盘 :w! 若文件属性为“只读”时,强制写入该文件.不过需要注意,这个是在你的权限可以改变的情况下才能成立 :q 离开vim :q! 修改过文件,又不想保存 :wq 保存后离开 :w ...

  10. Android(java)学习笔记3:线程的优先级

    1. Java线程的优先级从1到10级别,值越大优先级越高线程默认优先级是5.值越大优先级越高 (1) 继承自Thread类创建线程类: package cn.itcast_04; public cl ...