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. JavaWEB - 静态include指令、动态Include指令

    (一)使用静态include指令 <%@ page language="java" contentType="text/html; charset=gb2312&q ...

  2. ffmpeg代码实现自定义encoder

    1.概述 本文主要讲述如何用ffmpeg代码实现自己的encoder. 2.代码 /* *本程序主要实现一个自己的encoder并加入到encoder链中去,供api调用 *作者:缪国凯(MK) *8 ...

  3. org.springframework.web.client.HttpClientErrorException: 400 null

    异常代码: org.springframework.web.client.HttpClientErrorException: 400 null 已解决. 百度了一下400代表无法解析请求. 说明请求是 ...

  4. protocol 和 delegate

    步骤 1.发出协议(在发协议者.h文件 下@interface-@end 上边) @protocol hireOneMaid <NSObject> @required//必须要实现的方法( ...

  5. DSP基础

    CCS V5的使用 CCS安装与设置

  6. poj3414Pots(倒水BFS)

    Pots Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13231   Accepted: 5553   Special J ...

  7. 问题6:如何让字典保持有序(使用collections的OrderedDict方法)

    from collections imort OrderedDict d = OrderedDict() d['aa'] = (1, 30) d['bb'] = (2, 31) d['cc'] = ( ...

  8. js字符串API

    1.charAt(n) :返回字符串n位置的字符 2.substr(n,m):n:开始截取的位置 m:截取的长度 2.substring(n,m):n:开始截取的位置 m:截取结束的位置 3.repl ...

  9. MD5 校验文件

    https://blog.csdn.net/wudishine/article/details/42466831 MD5.h #ifndef MD5_H #define MD5_H #include ...

  10. Sequence Models 笔记(一)

    1 Recurrent Neural Networks(循环神经网络) 1.1 序列数据 输入或输出其中一个或两个是序列构成.例如语音识别,自然语言处理,音乐生成,感觉分类,dna序列,机器翻译,视频 ...