在Flask中并没有限制我们使用哪种方式来操作数据库,如果使用原生SQL的方式来操作数据库,随着项目代码量的提升会发现有大量操作数据库的冗余代码,以及大量SQL语句与逻辑代码杂糅在一起不利于核心代码的读写,并且SQL语句的利用率不高。当更换数据库产品时有些特定SQL语句需要重写,而使用ORM框架能很好的避免上述问题。

ORM

ORM(Object Relational Mapping)中文翻译过来叫作对象关系映射,它把一个类映射成数据库里的一张表而属性映射成数据库表的列,每一个实例对象对应数据库表里的一行数据。通过它我们可以直接使用面向对象的方式来编写程序而不再直接书写原生的SQL语句,而且大部分ORM框架支持多种数据库只需很少的配置即可完成数据库产品的更换,在Python中常见的ORM框架有SQLAlchemy、Django Model、PeeWee等。

Flask-SQLAlchemy扩展

SQLAlchemy是目前很流行的ORM框架,Flask-SQLAlchemy扩展可以帮助我们在Flask中方便的使用SQLAlchemy

安装Flask-SQLAlchemy扩展,假如你没有安装SQLAlchemy会一并安装上1pip install flask-sqlalchemy

数据模型

模型是对数据抽象并提供通用访问接口的一种方式,一个模型类对应于数据库中的一张表。

定义模型类1

2

3

4

5

6

7

8

9

10

11

12

13

14

15from flask import Flask

from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///test.db"

db = SQLAlchemy(app)

# 分类

class Category(db.Model):

__tablename__ = "t_category"

id = db.Column(db.Integer, primary_key=True)

name = db.Column(db.String(50))

db.create_all()

代码说明: 所有模型必须继承至 db.Model,使用 __tablename__ 属性指定数据库中表名,如果不指定表名默认为类名。模型类的属性对应于数据表中的列,通过 db.Column 类的实例来描述,最后 db.create_all() 会帮助我们创建表结构

连接数据库的信息通过app.config[“SQLALCHEMY_DATABASE_URI”]来指定,常见数据库的连接信息如下数据库连接地址SQLitesqlite:///文件名

MySQLmysql+pymysql://用户名:密码@主机:3306/数据库名

Oracleoracle+cx_oracle://用户名:密码@主机:1521/SID名

SQL Servermssql+pymssql://用户名:密码@主机:端口/数据库名

注: 上面有些URL中的协议部分有加号需要安装指定模块,如MySQL需要安装PyMySQL模块如果不书写加号部分会默认使用MySQLDB进行连接

描述列时常用的数据类型类型说明db.Integer整型

db.Float浮点型

db.String变长字符串

db.Date日期类型

db.DateTime日期时间类型

db.Text大文本

db.Boolean布尔型

描述列时还可以添加选项,常见如下选项名说明primary_key设置主键

default设置默认值

unique设置是否唯一

nullable设置是否允许为空

index设置是否添加索引

注: SQLAlchemy要求每个模型必须定义主键默认对主键进行自增,默认映射到数据库中的列名为自定义类的属性名称,如果想修改该值需要在db.Column()第一个参数指定

模型之间的关联

模型之间可以互相关联使得相关联的数据能够很容易的从数据库中取出,模型关联映射到数据库中为主外键关系。

一对多/多对一

这是最常见的一种关系,比如说一个分类下面有多篇文章1

2

3

4

5

6

7

8

9

10

11

12

13

14# 分类

class Category(db.Model):

__tablename__ = "t_category"

id = db.Column(db.Integer, primary_key=True)

name = db.Column(db.String(50))

posts = db.relationship("Post", backref="category")

# 文章

class Post(db.Model):

__tablename__ = "t_post"

id = db.Column(db.Integer, primary_key=True)

title = db.Column(db.String(50))

content = db.Column(db.Text)

category_id = db.Column(db.Integer, db.ForeignKey("t_category.id"))

代码说明: 在多的一端通过 db.ForeignKey 定义外键指向一的一端的主键列,该参数值格式为:表名.列名;通过 db.relationship 指定关系,第一个参数填写有关系的模型类,当该模型类还未定义可以先填写字符串底层会通过反射来获取,通过backref参数向有关系的一端添加一个可以引用自己的属性,该语句也可以定义在关系中的任意一方但必须指定的关系要明确。

一对一

常见的场景有一个人只有一个身份证,只需要把一对多关系中多的一端的外键指定为唯一值即可1

2

3

4

5

6

7

8

9

10

11

12

13# 人

class People(db.Model):

__tablename__ = "t_people"

id = db.Column(db.Integer, primary_key=True)

name = db.Column(db.String(15))

codes = db.relationship("Code", backref="people")

# 身份证

class Code(db.Model):

__tablename__ = "t_code"

id = db.Column(db.Integer, primary_key=True)

title = db.Column(db.String(18))

p_id = db.Column(db.Integer, db.ForeignKey("t_people.id"), unique=True)

多对多

常见的场景有一个用户对应多个角色,而一个角色同时也能对应多个用户,在关系型数据库中一般通过中间表的形式体现

方式一: 使用中间模型帮我们建立中间表1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19# 用户

class User(db.Model):

__tablename__ = "t_user"

id = db.Column(db.Integer, primary_key=True)

name = db.Column(db.String(15))

user_roles = db.relationship("UserRole", backref="user")

# 角色

class Role(db.Model):

__tablename__ = "t_role"

id = db.Column(db.Integer, primary_key=True)

name = db.Column(db.String(15))

role_users = db.relationship("UserRole", backref="role")

# 关系

class UserRole(db.Model):

__tablename__ = "t_user_role"

user_id = db.Column(db.Integer, db.ForeignKey("t_user.id"), primary_key=True)

role_id = db.Column(db.Integer, db.ForeignKey("t_role.id"), primary_key=True)

方式二: 手动创建中间表1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17t_user_role = db.Table("t_user_role",

db.Column("user_id", db.Integer, db.ForeignKey("t_user.id"), primary_key=True),

db.Column("role_id", db.Integer, db.ForeignKey("t_role.id"), primary_key=True)

)

# 用户

class User(db.Model):

__tablename__ = "t_user"

id = db.Column(db.Integer, primary_key=True)

name = db.Column(db.String(15))

roles = db.relationship("Role", backref="users", secondary=t_user_role)

# 角色

class Role(db.Model):

__tablename__ = "t_role"

id = db.Column(db.Integer, primary_key=True)

name = db.Column(db.String(15))

以上两种方式都能实现多对多关系,我个人更喜欢方式二因为方式一多了一个模型类操作起来更繁琐

表管理

在上面的例子中我们只使用了db.create_all(),他会扫描模型创建所有的表,如果想删除所有表使用如下语句1db.drop_all()

当然在实际项目中我们不会在代码中管理表一般会借助工具来生成,如使用Flask-Script扩展写一个命令函数,在Shell中执行上面的代码,更高级的使用Flask-Migrate扩展它不仅能创建表还能进行数据迁移。

操作数据

有了模型类也生成了表,接下来通过模型类对数据进行增删改查

新增

只需构建模型类的实例,添加进数据库会话即可1

2c = Category(name="Java")

db.session.add(c)

对于一对多/多对一关联关系1

2

3

4

5p = Post()

p.title = "Java入门示例"

p.content = "Hello World ...."

p.category = c

db.session.add(p)

对于多对多关系,下例采用方式二定义的多对多关系,至于方式一定义的关联关系操作与一对多类似1

2

3

4

5

6

7

8

9

10

11u = User(name="Harmel")

r1 = Role(name="ROOT")

r2 = Role(name="NONE")

db.session.add(r1)

db.session.add(r2)

u.roles = [r1, r2]

db.session.add(u)

# 也可以采用如下方式

u.roles.append(r1)

u.roles.append(r2)

修改

把查出来的对象更改属性后再次保存即可修改1

2

3

4# 根据ID查询

c = Category.query.get(1)

c.name = "Python"

db.session.add(c)

删除

显示删除1

2c = Category.query.get(1)

db.session.delete(c)

隐式删除就是在一对一或一对多中配置级联删除后,如果删除一的一端另一端的数据也会同步删除

查询

根据ID查询1c = Category.query.get(1)

查询所有1categorys = Category.query.all()

查询总记录数1count = Category.query.count()

将结果排序1

2

3

4

5# 默认是顺序排列

categorys = Category.query.order_by("name").all()

# 倒序排列

categorys = Category.query.order_by("name desc").all()

分页查询1

2

3# offset 指定偏移量

# limit 指定查几条

categorys = Category.query.offset(1).limit(2).all()

Flask-SQLAlchemy提供了分页方法1

2

3

4

5

6

7

8

9# 第一个参数指定第几页

# 第二个参数指定每页多少条数据

paginate = Category.query.paginate(1, 5)

categorys = paginate.items

page_count = paginate.pages # 总页数

has_prev = paginate.has_prev # 是否有上一页

has_next = paginate.has_next # 是否有下一页

prev_paginate = paginate.prev() # 上一页

next_paginate = paginate.next() # 下一页

等值过滤1

2

3

4categorys = Category.query.filter_by(name="Python").all()

# 由于all()返回的是一个集合,如果只想取第一个可以这样

category = Category.query.filter_by(name="Python").first()

模糊查询1categorys = Category.query.filter(Category.name.ilike('%o%')).all()

事务

对于每次的增、删、改操作都必须要提交事务1db.session.commit()

我们可以配置让其自动提交1app.config["SQLALCHEMY_COMMIT_ON_TEARDOWN"] = False

回滚事务1db.session.rollback()

flask orm 数据库_Flask:使用ORM框架操作数据库相关推荐

  1. yii mysql_Yii2框架操作数据库的方法分析【以mysql为例】

    本文实例讲述了Yii2框架操作数据库的方法.分享给大家供大家参考,具体如下: 准备数据库 DROP TABLE IF EXISTS `pre_user`; CREATE TABLE `pre_user ...

  2. python数据库操作框架_python bottle 框架操作数据库

    python操作mysql数据库用MySQLdb模板,操作postgresql则用psycopg2模块 安装MySQLdb(用yum安装,好像只能与mysql5.1版本配合使用):yum instal ...

  3. MySQL数据库应用第3章操作数据库

    MySQL安装好以后,首先需要创建数据库,这是使用mysql各种功能的前提.本章将详细介绍数据的基本操作,主要内容包括数据库的创建和删除,不同类型的数据存储引擎和存储引擎的选择. 学习目标: 1.掌握 ...

  4. python多线程读取数据库数据_Python基于多线程操作数据库相关知识点详解

    Python基于多线程操作数据库相关问题分析 本文实例分析了Python多线程操作数据库相关问题.分享给大家供大家参考,具体如下: python多线程并发操作数据库,会存在链接数据库超时.数据库连接丢 ...

  5. 数据库1:数据库、DDL数据库定义语言、DML操作数据库语言、DQL条件查询语句

    数据库 SQL(Structure Query Language)语言是数据库的核心语言. SQL语言共分为四大类:数据查询语言DQL,数据操做语言DML,数据定义语言DDL,数据控制语言DCL. 1 ...

  6. c/c++连接mysql数据库设置及乱码问题(vs2013连接mysql数据库,使用Mysql API操作数据库)...

    我的安装环境: (1)vs2013(32位版) (vs2013只有32位的 没有64位的,但是它可以编译出64位的程序)  : (2)mysql-5.7.15(64位) vs2013中的设置(按步骤来 ...

  7. medoo php 教程,Medoo框架操作数据库

    摘要:Medoo框架好处:轻量 简单 强大 兼容 安全 免费Medoo框架使用步骤:1.安装:1>通过官网下载  2>使用composer2.配置    #1.导入框架    requir ...

  8. 记录Python使用Django框架操作数据库遇到的问题与流程

    ** python学习使用Django框架连接mysql数据库的步骤和遇到的一些问题 ** 配置数据库: 项目的settings.py文件的77行修改如下: DATABASES = {'default ...

  9. 使用 greenDao 框架 操作数据库

    0.效果图 步骤: 1.新建java项目,生成实体类等代码.需要的jar包: freemarker-2.3.10.jar , greendao-generator-1.3.1.jar import j ...

最新文章

  1. python怎么读文件名-python读取文件名并改名字的实例
  2. Linux C : 进程管理实验:创建进程、上下文切换
  3. Oracle区概念总结
  4. 在WebLogic 12c上运行RichFaces
  5. PKCS #1 RSA Encryption Version 1.5
  6. java如何简单的将一个三位正整数分解成三个数
  7. android右滑返回动画,Android仿微信右滑返回功能的实例代码
  8. 港澳台手机号正则表达式
  9. java 监听udp_Java实现Udp网络编程
  10. el-table 样式设置
  11. 【C语言经典100题】乒乓球队的比赛
  12. Django模板语言DTL中的变量和标签
  13. 高数笔记基础篇(更完)
  14. c#后台如何导出excel到本地_C#导出EXCEL方法总结
  15. Linux C语言实现TCP客户端与服务器
  16. 无盘服务器0x00000124,蓝屏0x00000124,懂的帮我一下
  17. 扩展城市信道etu模型matlab仿真,【SDR】LTE信道仿真模型-EPA信道
  18. 基于STM32F429的RGB屏使用
  19. 天枰座定时任务处理框架
  20. Python测试工具-Pytest使用详解

热门文章

  1. mysql重复上一行的快捷_MySql三种避免重复插入数据的方法
  2. Jsp+SSH+Mysql实现的校园课程作业网
  3. SpringBoot实现的简单停车位管理系统
  4. 通讯录管理系统课设使用c编写基于链表增查删改分组文本操作随程序实时同步
  5. 为什么要文件名和类名一样php_php文件名和类名相同时include不起作用?
  6. android studio创建构造方法,使用Android studio创建你的第一个项目
  7. iis php5.4配置_PHP5.4 + IIS + Win2008 R2 配置
  8. WPF Logical Tree vs. Visual Tree
  9. 力扣——字符串转换整数(atoi)
  10. jQuery中animate的一个隐藏很深的坑