Flask:数据库管理
为什么不使用SQL语句,而使用ORM框架管理数据库?首先,在python程序中嵌入原生SQL语句,不方便维护,ORM框架使用面向对象思想,使用较方便;第二,如果更换底层数据库引擎,ORM框架不需要修改代码。ORM框架也有其弊端,如有一定的性能损耗,且高级查询编写复杂,有一定的学习成本。
1、配置数据库链接
Flask-SQLAlchemy 中,数据库使用 URL 指定。一般开发环境使用SQLite,生产环境使用MySQL,使用MySQL时,还需要再安装相应的依赖包。
几种最流行的数据库引擎使用的 URL 格式:
数据库引擎 | URL |
---|---|
MySQL | mysql://username:password@hostname/database |
SQLite(Linux,macOS) | sqlite:////absolute/path/to/database |
SQLite(Windows) | sqlite:///c:/absolute/path/to/database |
配置数据库:
app.config['SQLALCHEMY_DATABASE_URI'] ='sqlite:///' + os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# SQLALCHEMY_TRACK_MODIFICATIONS 参数决定是否追踪对象的修改,SQLAlchemy建议配置此变量,不然会有警告。
2、定义模型
模型这个术语表示应用使用的持久化实体。在ORM中,模型一般是一个表示数据表的类,类的实例对应一条记录,类中的属性对应于数据库表中的列。
所以模型定义,类似原生SQL的CREATE TABLE语句:
class Role(db.Model):
# 定义表名
__tablename__ = 'roles'
# 定义字段
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
def __repr__(self):
return '<Role %r>' % self.name
常用列类型与列选项:https://www.cnblogs.com/adamans/articles/9815040.html
3、关系
关系型数据库的表和表之间需要建立“一对多”,“多对一”和“一对一”的关系,这样才能够按照应用程序的逻辑来组织和存储数据。在关系型数据库中,关系是通过主键和外键来维护,其中外键既可以通过数据库来约束,也可以不设置约束,仅依靠应用程序的逻辑来保证,这里讨论使用数据库来约束的情况。
3.1 一对多
例如角色和用户是一对多关系,一个用户只对用一个角色,而一个角色可以对应多个用户:
class Role(db.Model):
# ...
users = db.relationship('User', backref='role')
class User(db.Model):
# ...
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
添加到 User
模型中的 role_id
列被定义为外键,就是这个外键建立起了关系。传给 db.ForeignKey()
的参数 'roles.id'
表明,这列的值是 roles
表中相应行的 id
值。
添加到 Role
模型中的 users
属性代表这个关系的面向对象视角,对于一个 Role
类的实例,其 users
属性将返回与角色相关联的用户组成的列表。db.relationship()
的第一个参数表明这个关系的另一端是哪个模型,backref
参数向 User
模型中添加一个 role
属性,从而定义反向关系。通过 User
实例的这个属性可以获取对应的 Role
模型对象,而不用再通过 role_id
外键获取。
3.2 一对一
一对一关系可以用前面介绍的一对多关系表示,但调用 db.relationship()
时要把 uselist
属性设为 False
,把“多”变成“一”。
3.3 多对一
多对一关系从“多”这一侧看,就是一对多关系,对调两个表即可。
3.4 多对多
上述关系至少都有一侧是单个实体,所以记录之间的联系通过外键实现,让外键指向那个实体。但是,可能两侧都是“多”的关系,如有学生表和课程表,学生可能选多个课程,课程也可能被多个学生选。这种时候一般使用第三张表(即关联表)来表示关系:
class c(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
classes = db.relationship('Class',
secondary=registrations,
backref=db.backref('students', lazy='dynamic'),
lazy='dynamic')
class Class(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
registrations = db.Table('registrations',
db.Column('student_id', db.Integer, db.ForeignKey('students.id')),
db.Column('class_id', db.Integer, db.ForeignKey('classes.id'))
)
多对多关系仍使用定义一对多关系的 db.relationship()
方法定义,但在多对多关系中,必须把 secondary
参数设为关联表。多对多关系可以在任何一个类中定义,backref
参数会处理好关系的另一侧。关联表就是一个简单的表,不是模型,SQLAlchemy 会自动接管这个表。
Student
中classes
关系使用列表语义,这样处理多对多关系特别简单:
# 查看Student实例所选课程、Class实例被选情况
>>> s.classes.all()
>>> c.students.all()
# 增加课程
>>> s.classes.append(c)
>>> db.session.add(s)
>>> db.session.commit()
# 取消选课
>>> s.classes.remove(c)
>>> db.session.add(c)
>>> db.session.commit()
关联表使用db.Table类定义
指定了lazy='dynamic' 参数,所以关系两侧返回的查询都可接受额外的过滤器
3.5 自引用
多对多有种特殊情况,即关系中的两侧都在同一个表中,这种关系称为自引用关系。如用户表之间的关注关系,
4、数据库操作
对数据库的改动通过数据库会话管理,在 Flask-SQLAlchemy 中,数据库会话由 db.session 表示。调用 db.session.commit()提交事务,db.session.rollback() 回滚事务。
① 创建表、删除表
db.create_all()
db.drop_all()
② CREATE
admin_role = Role(name='Admin')
db.session.add(admin_role)
db.session.add_all([admin_role, mod_role])
db.session.commit()
③ UPDATE
admin_role.name = 'Administrator'
db.session.add(admin_role)
db.session.commit()
④ DELETE
db.session.delete(mod_role)
db.session.commit()
⑤ READ
<模型类>.query.<过滤方法>.<查询方法>
User.query.all()
User.query.filter_by(role=user_role).all()
Role.query.filter_by(name='User').first()
# 查看查询API...
5、文档
sqlalchemy中文文档:https://www.osgeo.cn/sqlalchemy/
sqlalchemy英文文档:https://docs.sqlalchemy.org/
flask-sqlalchemy文档:http://www.pythondoc.com/flask-sqlalchemy/index.html
Flask:数据库管理的更多相关文章
- python+mysql+flask创建一个微博应用(持续更新)
微博应用的结构: 用户管理,包括登录管理,会话,用户角色,个人档案及用户头像. 数据库管理,包括数据库迁移处理. Web表单支持,包括字段检验和用于防止垃圾邮件的验证码功能. 大数据的分页功能. 全文 ...
- 狗书无敌,天下第一(flask基础)
为什么选择使用flask? 和其他框架相比, Flask 之所以能脱颖而出,原因在于它让开发者做主,使其能对程序具有全面的创意控制. 在 Flask 中,你可以自主选择程序的组件,如果找不到合适的,还 ...
- flask 面试题
1,什么是Flask,有什么优点?概念解释Flask是一个Web框架,就是提供一个工具,库和技术来允许你构建一个Web应用程序.这个Web应用程序可以是一些Web页面,博客,wiki,基于Web的日里 ...
- [Python]Python入坑小项目推荐- Flask example minitwit
知乎上看到的Python练手项目推荐,链接见:https://www.zhihu.com/question/29372574,不知道是我自己懒得看还是理解力不行,这些项目真的是...太大了呀~~~~ ...
- Flask关于请求表单的粗浅应用及理解+简单SQL语句温习
1.请求表单 请求表单的知识点是flask数据请求中很小的一部分,首先要了解一下GET和POST请求:http://www.w3school.com.cn/tags/html_ref_httpmeth ...
- Python的Flask框架与数据库连接的教程
命令行方式运行Python脚本 在这个章节中,我们将写一些简单的数据库管理脚本.在此之前让我们来复习一下如何通过命令行方式执行Python脚本. 如果Linux 或者OS X的操作系统,需要有执行脚 ...
- django和flask的区别
转载至https://blog.csdn.net/tulan_xiaoxin/article/details/79132214 (1)Flask Flask确实很“轻”,不愧是Micro Framew ...
- pthon web框架flask(一)
pthon web框架优劣: 知乎上有一个讨论Python 有哪些好的 Web 框架?,从这个讨论中最后我选择了flask,原因是: Django,流行但是笨重,还麻烦,人生苦短,肯定不选 web.p ...
- 详说Flask、Django、Pyramid三大主流 Web 框架
前言 目前随着 Python 在大数据.云计算.人工智能方面的热度,Python Web 应该也会被更多企业了解使用. Python Web 框架千万种,没必要都去了解和学习,身边总有人说高手都用 F ...
随机推荐
- Codeforces Round #585 (Div. 2) E. Marbles(状压dp)
题意:给你一个长度为n的序列 问你需要多少次两两交换 可以让相同的数字在一个区间段 思路:我们可以预处理一个数组cnt[i][j]表示把i放到j前面需要交换多少次 然后二进制枚举后 每次选择一个为1的 ...
- Educational Codeforces Round 90 (Rated for Div. 2) A. Donut Shops(数学)
题目链接:https://codeforces.com/contest/1373/problem/A 题意 有两种包装的甜甜圈,第一种 $1$ 个 $a$ 元,第二种 $b$ 个 $c$ 元,问买多少 ...
- qmh的测试1
题目:传送门 首先输入一个n,之后输入n个数a(1<=a<=1e7),对这n个数排序后,你需要找到所有的它们连续的长度.把这些连续的长度排序后输出 输入 输入: 8 1 5 2 7 4 5 ...
- Codeforces Round #646 (Div. 2) C. Game On Leaves (贪心,博弈)
题意:给你一棵树,每次可以去掉叶节点的一条边,Ayush先开始,每回合轮流来,问谁可以第一个把\(x\)点去掉. 题解:首先如果\(x\)的入度为\(1\),就可以直接拿掉,还需要特判一下入度为\(0 ...
- HDU - 1789 dp
题意: 众所周知lyb根本不学习.但是期末到了,平时不写作业的他现在有很多作业要做. CUC的老师很严格,每个老师都会给他一个DDL(deadline). 如果lyb在DDL后交作业,老师就会扣他的分 ...
- windows 系统下安装kibana和sense
目前最新版本已经不需要安装sense了,而是使用Dev Tools工具: 下面进行下载和安装kibana. 点击下载:https://artifacts.elastic.co/downloads/ki ...
- Numpy Quickstart tutorial
此文是关于Numpy的一些基本用法, 内容来源于Numpy官网:https://docs.scipy.org/doc/numpy-dev/user/quickstart.html 1.The Basi ...
- Nginx基础 - 配置缓存web服务
1.缓存配置语法 1)proxy_cache配置语法 Syntax: proxy_cache zone | off; Default: proxy_cache off; Context: http, ...
- spring再学习之AOP实操
一.spring导包 2.目标对象 public class UserServiceImpl implements UserService { @Override public void save() ...
- LeetCode 题解 593. Valid Square (Medium)
LeetCode 题解 593. Valid Square (Medium) 判断给定的四个点,是否可以组成一个正方形 https://leetcode.com/problems/valid-squa ...