Flask—05-理解掌握flask数据模型(01)
数据模型
数据库回顾
- 分类:
- 关系型数据库:MySQL、sqlite、…
- 非关系型数据库:Redis、MongoDB、…
- 操作:
- 执行原生SQL语句,每次都需要拼接SQL语句,非常繁琐而且特别容易出错。
- ORM(对象关系映射),使用ORM可以通过对对象的操作完成对数据库的操作。
flask-sqlalchemy
说明:其实是sqlalchemy扩展库在flask中的移植库,通过了绝大多数关系型数据库的支持(ORM)
安装:
pip install flask-sqlalchemy
连接地址配置:
- 名称:
SQLALCHEMY_DATABASE_URI
- 格式:
- sqlite:
sqlite:/// + 数据库文件名
- MySQL:
数据库名+驱动名://用户名:密码@主机:端口/数据库
- sqlite:
- 名称:
使用:
# 配置数据连接地址
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)的更多相关文章
- Flask 框架理解(一)
Flask 框架理解(一) web 服务器 , web 框架 以及 WSGI 这里说的 web 服务器特指纯粹的 python HTTP 服务器(比如 Gunicorn,而不是 Apache,Ngin ...
- python 全栈开发,Day142(flask标准目录结构, flask使用SQLAlchemy,flask离线脚本,flask多app应用,flask-script,flask-migrate,pipreqs)
昨日内容回顾 1. 简述flask上下文管理 - threading.local - 偏函数 - 栈 2. 原生SQL和ORM有什么优缺点? 开发效率: ORM > 原生SQL 执行效率: 原生 ...
- Flask最强攻略 - 跟DragonFire学Flask - 第六篇 Flask 中内置的 Session
Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from ...
- Flask最强攻略 - 跟DragonFire学Flask - 第四篇 Flask 中的模板语言 Jinja2 及 render_template 的深度用法
是时候开始写个前端了,Flask中默认的模板语言是Jinja2 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符 ...
- 使用Flask+uwsgi+Nginx部署Flask正式环境
环境准备 在开始正式讲解之前,我们将首先进行环境准备. Step1:安装Python,pip以及nginx: sudo apt-get update sudo apt-get install pyth ...
- Flask 入门一( flask 框架和 flask-script 库)
Flask 入门一( flask 框架 和 flask-script 库) 一.Flask框架: 1.简介 Flask是一个非常小的Python Web框架,被称为微型框架:只提供了一个稳健的核心,其 ...
- 初识Flask框架,以及Flask中的模板语言jinjia2和Flask内置的Session
一.web框架的对比 首先我们先来看下比较火的web框架 1.Django: 优点:大而全,所有组件都是组织内部开发高度定制化,教科书级别的框架 缺点:大到浪费资源,请求的时候需要的资源较高 2.Fl ...
- Flask(3)- flask中的CBV、werkzeug+上下文初步解读、偏函数和线程安全
一.flask中的CBV 对比django中的CBV,我们来看一下flask中的CBV怎么实现? from flask import Flask, render_template, url_for, ...
- 第七篇 Flask实例化配置及Flask对象配置
一.Flask对象的配置 Flask 是一个非常灵活且短小精干的web框架 , 那么灵活性从什么地方体现呢? 有一个神奇的东西叫 Flask配置 , 这个东西怎么用呢? 它能给我们带来怎么样的方便呢? ...
- flask 第六篇 flask内置的session
Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from ...
随机推荐
- 项目搭建系列之二:SpringMVC框架下配置MyBatis
1.什么是MyBatis? MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis ...
- git stash压栈
git stash 用于暂存当前正在进行的工作,如想pull最新的代码,又不想加新的commit,或者为了fix一个紧急的bug,先stash,返回到自己上一个commit. 修改完bug后,再执行g ...
- 关于c3p0连接池连接mysql数据库需要注意的几点
什么是数据库连接池: 用池来管理Connection,这可以重复使用Connection.有了池,所以我们就不用自己来创建Connection,而是通过池来获取Connection对象. 当使用完Co ...
- 利用函数回调获取setInterval中返回的值
我们都知道,定时器里面想返回值如果你用return根本没作用,那么怎么拿到定时器所返回的值呢, 现在只需要利用回调函数,给主函数传一个函数类型的参数callback,然后把想要返回的num再传给cal ...
- 深度语义匹配模型-DSSM 及其变种
转自:http://ju.outofmemory.cn/entry/316660 感谢分享~ DSSM这篇paper发表在cikm2013,短小但是精炼,值得记录一下 ps:后来跟了几篇dssm的pa ...
- uwsgi特性
uwsgi 特性 官网参考 X-Sendfile仿真 即使前端 代理/webserver 不支持X-Sendfile (或者不能访问静态资源),可以使用 uwsgi 内部的 offloading 来模 ...
- sql developer中英文切换
今天使用oracle sql developer时做调优建议时找到的建议显示为?的乱码,本人sql developer为中文版,修改为英文版后问题解决. 查看帮助菜单中的属性选项卡,user.lang ...
- March 11 2017 Week 10 Saturday
Wisdom outweighs any wealth. 智慧比财富更有价值. Wisdom can create wealth if used in proper ways, it can help ...
- vim编辑下几个退出保存的命令
:w 将数据写入硬盘 :w! 若文件属性为“只读”时,强制写入该文件.不过需要注意,这个是在你的权限可以改变的情况下才能成立 :q 离开vim :q! 修改过文件,又不想保存 :wq 保存后离开 :w ...
- Android(java)学习笔记3:线程的优先级
1. Java线程的优先级从1到10级别,值越大优先级越高线程默认优先级是5.值越大优先级越高 (1) 继承自Thread类创建线程类: package cn.itcast_04; public cl ...