Flask ORM

在Django框架中内部已经提供ORM这样的框架,来实现对象关系映射,方便我们操作数据库。如果想在Flask中也达到这样效果,需要安装一个第三方来支持。

SQLAlchemy是一个关系型数据库框架,它提供了高层的ORM和底层的原生数据库的操作。flask-sqlalchemy是一个简化了SQLAlchemy操作的flask扩展。

安装

pip install flask-sqlalchemy

这里以mysql数据库为例

安装pymysql

pip install pymysql

相关配置

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import pymysql pymysql.install_as_MySQLdb()
app = Flask(__name__)
# 设置连接数据库的URL
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:123456@127.0.0.1:3306/db_flask' # 数据库和模型类同步修改
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True # 查询时会显示原始SQL语句
app.config['SQLALCHEMY_ECHO'] = True
# 管理app
db = SQLAlchemy(app)

字段类型

类型 对应python中 说明
Integer int 普通整数,一般是32位
SmallInteger int 取值范围小的整数,一般是16位
BigInteger int或long 不限制精度的整数
Float float 浮点数
Numeric decimal.Decimal 普通整数,一般是32位
String str 变长字符串
Text str 变长字符串,对较长或不限长度的字符串做了优化
Unicode unicode 变长Unicode字符串
UnicodeText unicode 变长Unicode字符串,对较长或不限长度的字符串做了优化
Boolean bool 布尔值
Date datetime.date 时间
Time datetime.datetime 日期和时间
LargeBinary str 二进制文件

约束类型

选项 说明
primary_key 如果为True,代表表的主键
unique 如果为True,代表这列不允许出现重复的值
index 如果为True,为这列创建索引,提高查询效率
nullable 如果为True,允许有空值,如果为False,不允许有空值
default 为这列定义默认值

关系类型

选项 说明
backref 在关系的另一模型中添加反向引用
primary join 明确指定两个模型之间使用的联结条件
uselist 如果为False,不使用列表,而使用标量值
order_by 指定关系中记录的排序方式
secondary 指定多对多中记录的排序方式
secondary join 在SQLAlchemy中无法自行决定时,指定多对多关系中的二级联结

创建

在Flask-SQLAlchemy中,插入、修改、删除操作,均由数据库会话管理。会话用db.session表示。在准备把数据写入数据库前,要先将数据添加到会话中然后调用commit()方法提交会话。

如果失败还可以回滚:db.rollback(),实现回话提交数据到以前的状态

模型类
"""
相关配置的代码 记得改为你自己的数据库
""" class Type(db.Model):
__tablename__ = 'tbl_type' # 表的名字 如果不写就以类名命名
id = db.Column(db.Integer,primary_key=True) # 主建
name = db.Column(db.String)
id = db.Column(db.Integer, primary_key=True) # 主键
name = db.Column(db.String(32), unique=True) # 名字 # 数据库中不存在的字段,只是为了查找和反向查找。
# backref:在关系的另一模型中添加反向引用
heros = db.relationship("Hero", backref='type') # 英雄
class Hero(db.Model):
# 表名
__tablename__ = 'tbl_heros'
# 数据库真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主键
name = db.Column(db.String(64), unique=True) # 名字
gender = db.Column(db.String(64)) # 性别 # 外键 一个射手对应很多英雄
type_id = db.Column(db.Integer, db.ForeignKey("tbl_types.id")) if __name__ == "__main__":
db.create_all() # 创建表 type1 = Type(name='射手')
db.session.add(type1) # 添加到会话
db.session.commit() # 提交 type2 = Type(name='坦克')
db.session.add(type2)
db.session.commit() type3 = Type(name='法师')
type4 = Type(name='刺客')
db.session.add_all([type3, type4]) # 添加多个
db.session.commit() hero1 = Hero(name='后羿', gender='男', type_id=type1.id)
hero2 = Hero(name='程咬金', gender='男', type_id=type2.id)
hero3 = Hero(name='王昭君', gender='女', type_id=type3.id)
hero4 = Hero(name='安琪拉', gender='女', type_id=type3.id)
hero5 = Hero(name='兰陵王', gender='男', type_id=type4.id) db.session.add_all([hero1, hero2, hero3, hero4, hero5]) # 添加多个
db.session.commit()

到你数据库查一下

查询

Flask-SQLAlchemy中常用过滤器:

过滤器 说明
filter() 把过滤器添加到原查询上,返回一个新查询
filter_by() 把等值过滤器添加到原查询上,返回一个新查询
limit() 使用指定的值限定原查询返回的结果
offset() 偏移原查询返回的结果,返回一个新查询
order_by() 根据指定条件对原查询结果进行排序,返回一个新查询
group_by() 根据指定条件对原查询结果进行分组,返回一个新查询

Flask-SQLAlchemy中常用执行器:

方法 说明
all() 以列表形式返回查询的所有结果
first() 返回查询的第一个结果,如果未查到,返回None
first_or_404() 返回查询的第一个结果,如果未查到,返回404
get() 返回指定主键对应的行,如不存在,返回None
get_or_404() 返回指定主键对应的行,如不存在,返回404
count() 返回查询结果的数量
paginate() 返回一个Paginate对象,它包含指定范围内的结果

这里举几个例子:

查全部分类:

Type.query.all()

根据分类过滤:

Type.query.filter_by(id = 1)

注意:

filter和 filter_by 的区别:

Type.query.filter(类.字段 == 条件) Type.query.filter_by(字段 = 条件)

逻辑与

Hero.query.filter_by(name='王昭君',type_id=3).first()

逻辑或

from sqlalchemy import or_

Hero.query.filter(or_(Hero.name.endswith('君'),Hero.type_id==3)).all()

排序

降序查询

Hero.query.order_by(Hero.id.desc()).all()

升序查询

Hero.query.order_by(Hero.id.asc()).all()

各种查询方法还有很多,大家可以去google或是百度

更新

  • 第一种

    hero = Hero.query.get(1)

    hero.name = '伽罗'

    db.session.add(hero)

    db.session.commit()
  • 第二种

    Hero.query.filter_by(id=1).update({"name":"虞姬","gender":"女"})

    db.session.commit()

删除

hero = Hero.query.get(4)

db.session.delete(hero)

db.session.commit()

模型迁移

在Django框架开发过程中,我们对数据库字段添加或删除,直接修改模型类,然后进行迁移可以了,非常方便。我们也想让Flask框架支持这样的操作,就需要使用Flask-Migrate扩展,来实现数据迁移。并且集成到Flask-Script中,所有操作通过命令就能完成。

安装插件

pip install Flask-Script

pip install flask-migrate

使用
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import pymysql
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager pymysql.install_as_MySQLdb()
app = Flask(__name__) # 通过脚本管理flask程序
manager = Manager(app)
"""
相关配置
"""
db = SQLAlchemy(app) # 创建数据库迁移对象
Migrate(app, db) # 向脚步管理添加数据库迁移命令 db指命令的别名
manager.add_command('db', MigrateCommand) """
模型代码
"""

初始化 只是在每个项目第一次生成迁移用到 以后就不用了

python3 app.py db init

app.py >> 你自己的文件名 db >> 上面指定的命令别名

在你的项目文件下 多出 migrations 的文件

生成迁移文件

python app.py db migrate -m 'first create'

提示:

INFO [alembic.runtime.migration] Context impl MySQLImpl.

INFO [alembic.runtime.migration] Will assume non-transactional DDL.

INFO [alembic.env] No changes in schema detected.

提交:

python flask_migrate_db.py db upgrade

ok 你的数据库已经有了数据

回退:

回退数据库时,需要指定回退版本号,由于版本号是随机字符串,为避免出错,建议先使用python flask_migrate_db.py db history命令查看历史版本的具体版本号,然后复制具体版本号执行回退。

python flask_migrate_db.py db downgrade base

python flask_migrate_db.py db downgrade 4cee71e47df3

4cee71e47df3 >>版本号

模型关系

在数据库中,我们知道数据关系大概有如下几种:一对一、一对多、多对多、自关联等。我们模型已经描述过了一对多,那么下面我们在用模型把其它关系也写出来。

一对一

# 文章模型
class Article(db.Model):
# 表名
__tablename__ = 'tbl_article' # 数据库真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主键
title = db.Column(db.String(128), unique=True) # 名字 # 方便查找,数据并不存在的字段
content = db.relationship('Acontent', backref='article', uselist=False) #一对一需要把uselist设置为False # 内容模型
class Acontent(db.Model):
# 表名
__tablename__ = 'tbl_acontent' # 数据库真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主键
content = db.Column(db.Text(4000)) # 名字
一对多
# 分类模型
class Category(db.Model):
# 表名
__tablename__ = 'tbl_category' # 数据库真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主键
name = db.Column(db.String(32), unique=True) # 名字
# 方便查找,数据并不存在的字段
article = db.relationship('Article', backref='category') # 文章模型
class Article(db.Model):
# 表名
__tablename__ = 'tbl_article' # 数据库真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主键
title = db.Column(db.String(128), unique=True) # 名字
category_id = db.Column(db.Integer, db.ForeignKey('tbl_category.id')) # 分类id
多对多
# 辅助表
tbl_tags = db.Table('tbl_tags',
db.Column('tag_id', db.Integer, db.ForeignKey('tbl_tag.id')),
db.Column('article_id', db.Integer, db.ForeignKey('tbl_article.id'))
) # 标签模型
class Tag(db.Model):
# 表名
__tablename__ = 'tbl_tag' # 数据库真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主键
name = db.Column(db.String(32), unique=True) # 名字 # 文章模型
class Article(db.Model):
# 表名
__tablename__ = 'tbl_article' # 数据库真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主键
title = db.Column(db.String(128), unique=True) # 名字
category_id = db.Column(db.Integer, db.ForeignKey('tbl_category.id')) # 分类id
# 方便查找,数据并不存在的字段
content = db.relationship('Acontent', backref='article')
tags = db.relationship('Tag', secondary=tbl_tags, backref='articles')
# secondary=tbl_tags, tbl_tags->辅助表的名字 注意!!!
自关联
# 地区模型
class Area(db.Model):
# 表名
__tablename__ = "tbl_area"
# 数据库真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主键
name = db.Column(db.Text, nullable=False) # 地区名字
parent_id = db.Column(db.Integer, db.ForeignKey("tbl_area.id")) # 父评论id # 方便查找,数据并不存在的字段
parent = db.relationship("Area", remote_side=[id]) # 自关联需要加remote_side

flask 数据库的有关操作就到此结束了,有什么问题可以给我留言,看到会回复大家的

喜欢就点播关注吧-_-!

flask数据操纵的更多相关文章

  1. flask+sqlite3+echarts2+ajax数据可视化

    前提: 准备Python + Flask+Sqlite3的平台环境(windows系统) 前面一节介绍flask怎么安装了,剩下sqlite3下载后解压,然后环境变量添加解压路径就行了 附加下载地址: ...

  2. flask+sqlite3+echarts2+ajax数据可视化报错:UnicodeDecodeError: 'utf8' codec can't decode byte解决方法

    flask+sqlite3+echarts2+ajax数据可视化报错: UnicodeDecodeError: 'utf8' codec can't decode byte 解决方法: 将 py文件和 ...

  3. Windows下快速安装Flask的一次经历

    前提: 1.已安装python版本(一般都是2.X) 2.已安装easy_install python安装,记得配置Python的环境变量,例如:我的直接在Path上加 G:\Python 验证安装P ...

  4. 使用Flask设计带认证token的RESTful API接口[翻译]

    上一篇文章, 使用python的Flask实现一个RESTful API服务器端  简单地演示了Flask实的现的api服务器,里面提到了因为无状态的原则,没有session cookies,如果访问 ...

  5. 使用python的Flask实现一个RESTful API服务器端[翻译]

    最近这些年,REST已经成为web services和APIs的标准架构,很多APP的架构基本上是使用RESTful的形式了. 本文将会使用python的Flask框架轻松实现一个RESTful的服务 ...

  6. python flask (一)

    from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World ...

  7. flask源码分析

    本flask源码分析不间断更新 而且我分析的源码全是我个人觉得是很beautiful的 1 flask-login 1.1 flask.ext.login.login_required(func),下 ...

  8. Python flask 基于 Flask 提供 RESTful Web 服务

    转载自 http://python.jobbole.com/87118/ 什么是 REST REST 全称是 Representational State Transfer,翻译成中文是『表现层状态转 ...

  9. Python flask @app.route

    转载自 http://python.jobbole.com/80956/ 下面是Flask主页给我们的第一个例子,我们现在就由它入手,深入理解“@app.route()”是如何工作的.         ...

随机推荐

  1. C - Alyona and SpreadsheetDP

    题目链接 题意在一个矩阵中,询问l~r行是否有一列满足mp[i][j]>=mp[i-1][j](i属于l~r)即非递减序列,是输出Yes,否输出No 用vector<vector<i ...

  2. 4_Prototype 原型

    #Prototype ``` // 不好的做法 monster ghost demon sorcerer class Spawner { public: virtual ~Spawner() {} ; ...

  3. 【二叉树的递归】04找出二叉树中路径和等于给定值的所有路径【Path Sum II】

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个二叉树和一个和,判断这个树 ...

  4. 【遍历二叉树】12往二叉树中添加层次链表的信息【Populating Next Right Pointers in Each Node II】

    本质上是二叉树的层次遍历,遍历层次的过程当中把next指针加上去. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ...

  5. 立方体贴图(Cubemap)

    http://blog.csdn.net/asdjy123/article/details/51190643 点击打开链接 好东西保存方便查看 立方体贴图(Cubemap) 原文 Cubemaps 作 ...

  6. 搭建DNS服务器-bind

    1. 安装 yum install -y bind-chroot yum install -y bind-utils service named-chroot start    2. 修改配置 增加一 ...

  7. 杂项:art-template-loader

    ylbtech-杂项:art-template-loader 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部 1. https://www.npmjs.com/p ...

  8. ES6学习之Reflect

    Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API Reflect设计目的: 将Object对象的一些明显属于语言内部的方法(比如Object.definePrope ...

  9. PHP二维数组,根据多个字段来排序

    如果是最最常见的二维数组排序, 大多数情况下也只用到二维: 用php内置函数 array_multisort( )  是最简单的: <?php 假设, $arr 是一个二维数组, $arg1是取 ...

  10. OpenXml 2.0 读取Excel

    Excel 单元格中的数据类型包括7种: Boolean.Date.Error.InlineString.Number.SharedString.String 读取源代码: List<strin ...