数据模型

数据库回顾

  • 分类:

    • 关系型数据库: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. node.js获取cookie

    node.js 获取cookie var Cookies ={}; if (req.headers.cookie != null) { req.headers.cookie.split(';').fo ...

  2. .net Ioc 之 Unity 适合刚开始使用

    介绍: 首先稍微介绍一下,Unity是微软patterns& practices组用C#实现的轻量级.可扩展的依赖注入容器,可通过代码或xml配置文件来配置对象之间的关系.那么通过一个简单的代 ...

  3. 继承Application管理生命周期

    继承Application实现Android数据共享 http://www.jianshu.com/p/75a5c24174b2 jessyan提出一个思路,用Application + 接口来管理扩 ...

  4. oracle学习篇九:同义词

    Oracle数据库中提供了同义词管理的功能.Oracle同义词是数据库方案对象的一个别名,经常用于简化对象访问和提高对象访问的安全性. 在Oracle中对用户的管理是使用权限的方式来管理的,也就是说, ...

  5. JSP 之 8种HTTP的请求方式 之 页面组成等

    HTTP请求的方法: HTTP/1.1协议中共定义了八种方法(有时也叫“动作”),来表明Request-URL指定的资源不同的操作方式   1.OPTIONS 返回服务器针对特定资源所支持的HTTP请 ...

  6. SmartUpload控件 中文乱码问题解决办法

    (乱码一般是三码不统一,但是当我们使用插件的时候,我们页面,后台,还有插件之间的转码不一定统一,导致了乱码这一问题) 首先,SmartUpload 的使用网上多的很,在这里就不在赘述,主要解决为什么乱 ...

  7. 买卖股票的最佳时机 - C++

    class Solution { public: /** * @param prices: Given an integer array * @return: Maximum profit */ in ...

  8. RAC修改spfile位置

    RAC修改spfile位置    [root@rac1 ~]# su - oracle  [oracle@rac1 ~]$ sqlplus  / as sysdba  SQL*Plus: Releas ...

  9. 长大Tips的第二步

    由于期末将至的缘故,组员们对于这次项目都开始表现出了懈怠的情绪,故而这一次并没有完成许多实质性的任务,相较于上一次,此次增添了登陆以及注册的功能,说来惭愧,虽然已经学习了数据库编程,可惜自己学艺不精并 ...

  10. Android(java)学习笔记7:多线程程序练习

    需求: 某电影院目前正在上映贺岁大片,共有100张票,而它有3个售票窗口售票,请设计一个程序模拟该电影院售票. 两种方式实现 A:继承Thread类 B:实现Runnable接 1. 首先我们利用方式 ...