Flask数据库学习
来源:互联网 发布:手机模板软件 编辑:程序博客网 时间:2024/06/05 01:17
数据库学习
@(Flask)
- 关系型数据库(SQL数据库)
- 文档数据库和键值对数据库 (NoSQL)
SQL数据库
表是关键。用表可以模拟程序中不同的实体。
- 主键:各行的唯一标识符。
- 外键:引用同一个表或不同表中的某行的主键。
表的列是固定的,所以这个可以对应到程序中的属性值。
关系型数据库复杂的地方在于联表查询。
NoSQL数据库
一般使用集合代替表。
使用文档代替记录。
NoSQL的设计方式使得联结变得困难。
所以NoSQL的设计很多地方需要反规范化操作,才能保证效率,但是数据重复是难以避免的了。
SQL or NoSQL
SQL数据库擅长处理:高效且紧凑的形式存储结构化数据。这种数据库需要花费大量精力保证数据库的一致性。
NoSQL数据库:放宽了对一致性的要求,获得了性能上的优势。
划重点:中小程序来说,SQL和NoSQL数据库都OK,且性能相当。
Python的数据库框架
Flask不限制使用何种类型的数据库包。
- MySQL
- Postgres
- SQLite
- Redis
- MonogoDB
- CouchDB
这些具体的数据库包。
数据库抽象层代码包
- SQLAlchemy
- MongoEngine
通过这些包可以处理高等级的Python对象。
选择考量因素
- 易用性:将高层的面向对象的操作转换为数据路指令。
- ORM : 对象关系映射
- ODM:对象文档映射
- 性能
- 可移植性
- Flask集成度:专门为Flask开发的扩展是首选。
Flask-SQLAlchemy
强大的关系型数据库框架。且提供了ORM,也有原生的SQL功能。
安装:pip install flask-sqlalchemy
数据库URL:
- MySQL :
mysql://username:password@hostname/database
- Postgres :
postgresql://username:password@hostname/database
- SQLite(Unix) :
sqlite:////absolute/path/to/database
- SQLite(Windows) :
sqlite:///c:/absolute/path/to/database
以MySQL为例,hostname是MySQL服务所在的主机。
可以是:
- localhost
- 远程服务器
数据库服务器上可以托管多个数据库,所以要指定databasename
。
可以看到SQLite没有hostname
,username
, password
,因为SQLite不用服务器,是本地的数据库服务,安卓手机就用的是SQLite数据库。
from flask_sqlalchemy import SQLAlchemy #引入数据库管理包basedir = os.path.abspath(os.path.dirname(__file__))app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir,'data.sqlite')db = SQLAlchemy(app)
db是SQLAlchemy类实例,表示的就是程序使用的数据库,通过db可以获得SQLAlchemy提供的所有功能。
定义模型
模型的含义:程序使用的持久化实体。
一般来说,数据库的天然属性就是持久化。
ORM下,模型是一个Python类,类的属性对应到数据库表中的列。
SQLAlchemy创建的数据库实例为模型提供了:
- 一个基类
- 一系列辅助类和辅助函数
用于定义模型的结构。
#定义模型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
类变量__tablename__
定义在数据库中说那个的表名。
db.Column()
类构造函数参数:
- 第一个参数是数据库列和模型属性的类型
- 第二个参数是可选配置选项
第一个参数类型不列举了,重点看第二个可选参数。
- primary_key 设置为True,表示这是主键
- unique 设置为True,表示这列不允许出现重复的值
- index 设置为True,为这列创建索引,提升查询效率
- nullable 设置为True,允许使用空值,反之,不允许用空值
- default 定义默认值
__repr__()
函数返回一个具有可读性的字符串表示模型,用于调试和测试。
关系
关系型数据库使用关系将不同的表中的行联系起来。
#在Role类中定义users = db.relationship('User',backref='role')#role_id位于users表中,这个是外键role_id = db.Column(db.Integer,db.ForeignKey('roles.id'))
db.relationship()
第一个参数表明这个关系的另一端是哪个模型,如果模型尚未定义,可使用字符串形式执行。
backref
参数向User
模型中添加一个role
属性。从而定义反向关系:通过这个属性可以替代role_id
访问Role模型。此时可以获取的是模型对象,不是外键的值。
注:关于反向关系的理解,可以点击参考相关解释。
定义关系时常用的配置选项:
- backref : 在关系的另一个模型中添加反向引用
- primaryjoin : 明确指定两个模型之间使用的联结条件,只在模棱两可的关系中需要指定。
- lazy : 指定如何加载相关记录。可选值有:
select
首次访问时按需加载immediate
源对象加载后就加载joined
加载记录但使用联结subquery
立即加载,但使用子查询noload
永不加载dynamic
不加载记录,但提供加载记录的查询
- uselist 若设为false,不使用列表,而使用标量值
- order_by 指定关系中记录的排序方式
- secondary 指定多对关系中关系表的名字
- secondaryjoin SQLAlchemy无法自行决定时,指定多对多关系中的二级联结条件
注:上面这些不是特别清晰,需要在实例中阐述。
创建表
- 根据模型创建数据库
方法:db.create_all()
函数
python hello.py shell>>> from hello import db>>> db.create_all()
删除旧表:db.drop_all()
插入行
#同样在shell下>>> from hello import Role, User>>> admin_role = Role(name='Admin')>>> mod_role = Role(name='Moderator')>>> user_role = Role(name='User')>>> user_john = User(username='john',role=admin_role)>>> user_susan = User(username='susan',role=user_role)
修改行
>>> admin_role.name = 'Administrator'>>> db.session.add(admin_role)>>> db.session.commit()
删除行
>>> db.session.delete(mod_role)>>> db.session.commit()
查询行
SQLAlchemy为每个模型类都提供给了query对象。
最基本的查询是:Role.query.all()
将返回表中的所有记录。
自然这个是很粗糙的,需要加条件过滤。
过滤器
进行更精确的数据库查询。
User.query.filter_by(role=user_role).all()
可以很方便查询SQLAlchemy生成的原生SQL查询语句:
>>> str(User.query.filter_by(role=user_role))
将得到原生的SQL语句。
常用过滤器
- filter() 将过滤器添加到原查询,返回一个新查询
- filter_by() 把等值过滤器加到原查询上,返回一个新查询
- limit() 使用指定的值限制原查询返回的结果数量,返回一个新查询
- offset() 偏移查询返回的结果,返回一个新查询
- order_by() 根据指定条件对远程讯结果进行排序,返回一个新查询
- group_by() 根据指定条件对元查询结果进行分组,返回一个新查询
指定过滤器后,通过调用all()
执行查询。
当然也有其他触发执行方法:
- all() 以列表形式返回查询的所有结果
- first() 返回查询的第一个结果,如果没有则返回None
- first_or_404() 返回查询的第一个结果,如果没有就终止请求,返回404错误响应
- get() 返回指定主键对应的行,没有则返回None
- get_or_404()
- count() 返回查询结果的数量
- paginate() 返回一个Pagniate对象,包含指定范围内的结果
视图函数中操作数据库
语法与上面在终端的用法相同。
集成Python shell
每次启动shell会话需要导入数据库实例和模型,为了避免重复,做些配置即可。
from flask_script import Shelldef make_shell_context(): return dict(app=app, db=db, User=User, Role=Role)manager.add_command("shell",Shell(make_context=make_shell_context))
用Flask-Migrate实现数据库迁移
用到再详谈。
- flask学习笔记(-数据库)
- Flask数据库学习
- Flask学习笔记之数据库
- [python3.6 flask web学习]Flask操作msql数据库
- Flask学习——数据库迁移
- Flask学习(四):数据库迁移
- Flask 数据库
- flask-数据库
- 《Flask development》flask数据库笔记
- 【Flask学习】
- flask 学习
- flask学习
- Flask学习
- flask 学习
- flask学习
- flask + MongoDB 学习笔记(2):增改删查数据库
- Flask学习-设备管理系统1:数据库修改,表单修改
- python flask学习笔记(四)-数据库操作
- 《APUE》读书笔记-第十七章高级进程间通信
- Android Opengl ES2.0 -实现的2种全景模式的查看方式
- java 内存中生成二维码,显示到浏览器中
- SpringBoot非官方教程 | 第十一篇:springboot集成swagger2,构建优雅的Restful API
- 博览网_C++_第一周_C++ complex类的实现(我的第一个c++程序)
- Flask数据库学习
- java线程中try catch finally块和throw抛出异常
- Ubuntu开发环境搭建(4)【安装repo】
- H5 WebSocket实现简单的实时通信
- Scala包和引用
- C语言中返回字符串函数的四种实现方法
- HDU-5867 Water problem(模拟)
- 算法导论 练习题 11.1-2
- 基于Kinect v2+PCL的模型奶牛重建(下)——点云融合