flask 使用Flask-SQLAlchemy管理数据库(连接数据库服务器、定义数据库模型、创建库和表)
使用Flask-SQLAlchemy管理数据库
扩展Flask-SQLAlchemy集成了SQLAlchemy,它简化了连接数据库服务器、管理数据库操作会话等各种工作,让Flask中的数据处理体验变得更轻松。首先使用pipenv安装Flask-SQLAlchemy以及其依赖(主要是SQLAlchemy):
pipenv install flask-sqlalchemy

下面在示例程序中实例化Flask-SQL-Alchemy提供的SQLAlchemy类,传入程序实例app,以完成扩展的初始化:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) db = SQLAlchemy(app)
为了便于使用,我们把实例化的扩展类对象命名为db。这个db对象代表我们的数据库,它可以使用Flask-SQLAlchemy提供的所有功能。
虽然我们要使用的大部分类和函数都有SQLAlchemy提供,但在Flask-SQLAlchemy中,大多数情况下,我们不需要手动从SQLAlchemy导入类或函数。在sqlalchemy和sqlalchemy.orm模块中实现的类和函数,以及其他几个常用的模块和对象都可以作为db对象的属性调用。当我们创建这样的调用时,Flask-SQLAlchemy会自动把这些调用转发到对应的类、函数或模块。
sqlite3数据库安装及客户端软件
sqlite下载地址:https://www.sqlite.org/download.html
下载sqlite-tools-win32-*.zip 和 sqlite-dll-win64-*.zip 压缩文件

解压后,创建文件夹 C:\sqlite3,在此文件夹下解压上面两个压缩文件,将得到 sqlite3.def、sqlite3.dll 和 sqlite3.exe 文件。

添加 C:\sqlite3到PATH环境变量,在命令提示符下,使用sqlite3命令,将显示如下

客户端软件官网:
https://www.softpedia.com/get/Internet/Servers/Database-Utils/SQLiteSpy.shtml
下载SQLiteSpy:

下载后:


打开sqlite的db文件:

连接数据库服务器
DBMS通常会提供数据库服务器运行在操作系统中。要连接数据库服务器,首先要为我们的程序指定数据库URL(Uniform Resource Identifier,统一资源标识符)。数据库URI是一串包含各种属性的字符串,其中包含了各种用于连接数据库的信息。
URI代表统一资源标识符,是用来标识资源的一组字符串。URL是它的子集。
下面是一些常用的DBMS以及其数据库URI格式实例。

在Flask-SQLAlchemy中,数据库的URI通过配置变量SQLALCHEMY_DATABASE_URI设置,默认为SQLite内存型数据库(sqlite: ///: memory: )。SQLite是基于文件的DBMS,不需要设置数据库服务器,只需要指定数据库文件的绝对路径。我们使用app.root_path来定位数据库文件的路径,并将数据库文件命名为data.db,如下所示
app.py:配置数据库URI
import os
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL', 'sqlite:///' + os.path.join(app.root_path, 'data.db'))
在生产环境下更换到其他类型的DBMS时,数据库URL会包含敏感信息,所以这里优先从环境变量DATABASE_URL获取(注意这里为了便于理解使用的是URL,不是URI)
SQLite数据库文件名不限定后缀,常用的命名方式有foo.sqlite, foo.db,或是注明SQLite版本的foo.sqlite3。
设置好数据库URI后,在python shell中导入并查看db对象会获得下面的输出:
>>> from app import db
C:\Users\Lenovo\.virtualenvs\Lenovo-ezd1lI9Y\lib\site-packages\flask_sqlalchemy\__init__.py:774: UserWarning: Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS is set. Defaulting SQLALCHEMY_DATABASE_URI to "sqlite:///:memory:".
'Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS is set. '
C:\Users\Lenovo\.virtualenvs\Lenovo-ezd1lI9Y\lib\site-packages\flask_sqlalchemy\__init__.py:794: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning.
'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '
>>> db
<SQLAlchemy engine=sqlite:///D:\flask\FLASK_PRACTICE\DataBase\data.db>

安装并初始化Flask-SQLAlchemy后,启动程序时会看到命令行下有警告,这是因为Flask-SQLAchemy建议你设置SQLALCHEMY_TRACK_MODIFICATIONS配置变量,这个配置变量决定是否追踪对象的修改,这用于Flask-SQLALchemy的事件通知系统。这个配置的默认值为None,如果没有特殊需要,可以设为False来关闭警告:
app.config['SQLALCHEMY_TRACE_MODIFICATIONS'] = False
再次导入db:
>>> from app import db
>>> db
<SQLAlchemy engine=sqlite:///D:\flask\FLASK_PRACTICE\DataBase\data.db>
>>>
定义数据库模型
用来映射到数据库表的python类通常被称为数据库模型(model),一个数据库模型类对应数据库中的一个表。定义模型即使用python类定义表模式,并声明映射关系。所有的模型都需要继承Flask-SQLAlchemy提供的db.Model基类。后续的例子是一个笔记程序,笔记保存到数据库中,你可以通过程序查询、添加、更新和删除笔记。
定义一个Note模型类,用来存储笔记。
app.py: 定义Note模型
class Note(db.Model):
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.Text)
在这个模型类中,表的字段(列)由db.Column类的实例表示,字段的类型通过Column类构造方法的第一个参数传入。在这个模型中,我们创建了一个类型为db.Integer的id字段和类型为db.Text的body列,分别存储整型和文本。常用的SQLAlchemy字段类型如下表:

字段类型一般直接声明即可,如果需要传入参数,也可以添加括号。对于类似String的字符串列,有些使句酷会要求限定长度,因此最好为其制定长度。虽然使用Text类型可以存储相对灵活的变长文本,但从性能上考虑,我们仅在必须的情况下使用Text类型,比如用户发表的文章和评论等不限长度的内容。
一般情况下,字段的长度是由程序设计者自定的。尽管如此,也有一些既定的约束标准,比如姓名(英文)的长度一般不超过70个字符,中文名一般不超过20个字符,电子邮件地址的长度不超过254个字符,虽然个主流浏览器支持长达2048个字符的URL,但在网站中用户资料设置的限度一般为255。对于超过一定长度的Email和URL,比如20个字符,会在显示时添加省略号的形式。显示的用户名(username)允许重复,通常要短一些,以不超过36个字符为佳。在程序中可以根据需要来设定。
当在数据库模型类中限制了字段的长度后,在接收对应数据的表单类字段里,也需要使用Length验证器来验证用户的输入数据。
默认情况下,Flask-SQLAlchemy会根据模型类的名称生成一个表名称,生成规则如下:
Message -> message # 单个单词转换为小写
FooBar -> foo_bar # 多个单词转换为小写并使用下划线分隔
Note类对应的表名即为note。如果想自己指定表名称,可以通过定义__tablename__属性来实现。字段名默认为类属性名,也可以通过字段类构造方法的第一个参数指定(如Column('data', String(50))),或使用关键字name。根据我们定义的Note模型类,最终将生成一个Note表,表中包含id和body字段。
除了name参数,实例化字段类时常用的字段参数如下表:

不需要在所有列都建立索引。一般来说,取值可能性多(比如姓名)的列,以及经常被用来作为排序的参数(如时间戳)更适合建立索引。
在实例化字段类时,通过把参数primary_key设为True可以将其定义为主键。在我们定义的Nore类中,id字段即表的主键(primary key)。主键是每一条记录(行)独一无二的标识,也是模型类中必须定义的字段,一般命名为id或pk。
创建数据库和表
如果把数据库(文件)看作一个仓库,为了方便取用,我们需要把货物按照类型分别放置在不同的货架上,这些货架就是数据库中的表。创建模型类后,我们需要手动创建数据库和对应的表,就是建库和建表。这通过对我们的db对象调用create_all()方法实现:
(Lenovo-ezd1lI9Y) D:\flask\FLASK_PRACTICE\DataBase>flask shell
App: app [production]
Instance: D:\flask\FLASK_PRACTICE\DataBase\instance
>>> from app import db
>>> from app import Note
>>> db.create_all()
如果将模型类定义在单独的模块中,那么必须再调用db.create_all()方法前导入相应模块,以便让SQLAlchemy获取模型类总定义的表信息,进而正确生成数据表。
通过下面的方式可以查看模型对应的SQL模式(建表语句):
>>> from app import db
>>> from app import Note
>>> db.create_all()
>>> print CreateTable(Note.__table__) CREATE TABLE note (
id INTEGER NOT NULL,
body TEXT,
PRIMARY KEY (id)
)
数据库和表一旦创建后,之后对模型的改动不会自动作用的实际的表中。比如在模型类中添加或删除字段,修改字段的名称和类型,这时再次调用create_all()也不会更新表结构。如果要使改动生效,最简单的方式是调用db.drop_all()方法删除数据库和表,然后再调用db.create_all()方法创建。
我们也可以自己实现一个自顶一个flask命令完成这个工作,例如:
app.py:用于创建数据库和表的flask命令
import click @app.cli.command()
def initdb():
db.create_all()
click.echo('Initialized database.')
在命令行输入flask initdb即可创建数据库和表:
(Lenovo-ezd1lI9Y) D:\flask\FLASK_PRACTICE\DataBase>flask initdb
Initialized database.
在开发程序或是部署后,我们经常需要在python shell中手动操作数据库(生产环境需注意备份),对于一次性操作,直接处理即可。对于需要重用的操作,我们可以编成flask命令、函数或是模型类的类方法。
flask 使用Flask-SQLAlchemy管理数据库(连接数据库服务器、定义数据库模型、创建库和表)的更多相关文章
- 在flask中使用flask-migrate管理数据库
Flask-Migrate是一个为Flask应用处理SQLAlchemy数据库迁移的扩展,使得可以通过Flask的命令行接口或者Flask-Scripts对数据库进行操作. 安装 pip3 insta ...
- 用 Flask 来写个轻博客 (4) — (M)VC_创建数据模型和表
目录 目录 前文列表 扩展阅读 定义数据模型 models 创建表 前文列表 用 Flask 来写个轻博客 (1) - 创建项目 用 Flask 来写个轻博客 (2) - Hello World! 用 ...
- MySQL数据库初识、下载使用(针对库、表、记录的增删改查)
今日内容概要 数据演变史 数据库软件的本质 MySQL简介 下载与安装 基本配置 基本SQL语句 内容详细 1.数据演变史 # 1.单独的文本文件 没有固定的存放位置和格式 文件名:user.txt ...
- MySQL之DDL数据定义语言:库、表的管理
库的管理 常用命令 #创建库 create database if not exists 库名 [ character set 字符集名]; create database if not exists ...
- Django之admin管理数据库,cookie验证及分页设置
一.admin管理数据库 1)models.py创建class类表 class Book(models.Model): name=models.CharField(max_length=) price ...
- 用 Flask 来写个轻博客 (8) — (M)VC_Alembic 管理数据库结构的升级和降级
Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 扩展阅读 Alembic 查看指令 manager db 的可用选项 ...
- 用 Flask 来写个轻博客 (13) — M(V)C_WTForms 服务端表单检验
目录 目录 前文列表 WTForms WTF 的基础使用 常用的字段类型 fieldsDateField fieldsIntegerField fieldsFloatField fieldsStrin ...
- Flask从入门到精通之使用Flask-SQLAlchemy管理数据库
Flask-SQLAlchemy 是一个Flask 扩展,简化了在Flask 程序中使用SQLAlchemy 的操作.SQLAlchemy 是一个很强大的关系型数据库框架,支持多种数据库后台.SQLA ...
- Flask 中的 SQLAlchemy 使用教程
Flask 是一个 python web micro framework.所谓微框架,主要是 flask 简洁与轻巧,自定义程度高.相比 django 更加轻量级. 之前一直折腾 django,得益于 ...
随机推荐
- Cglib动态代理实现原理
Cglib动态代理实现方式 我们先通过一个demo看一下Cglib是如何实现动态代理的. 首先定义个服务类,有两个方法并且其中一个方法用final来修饰. public class PersonSer ...
- one order 处理流程
- sap 查看自己代码的结构
1:进入系统X3C:然后输入T-CODE bsp_wd_cmpwb
- Java元注解—— @Retention @Target @Document @Inherited
java中元注解有四个: @Retention @Target @Document @Inherited: @Retention:注解的保留位置 @Retention(RetentionPolicy. ...
- Gradle全局变量定义及引用
在Project的build.gradle脚本中定义一些全局变量 ext { compileSdkVersion = 21 buildToolsVersion = "24.0.1" ...
- springboot测试
一.单元测试 在开发阶段的时候最重要的是单元测试了,springboot对单元测试的支持已经很完善了. 1.在pom包中添加spring-boot-starter-test包引用 <depend ...
- 2018-2019-1 20189221 《Linux内核原理与分析》第七周作业
2018-2019-1 20189221 <Linux内核原理与分析>第七周作业 实验六 分析Linux内核创建一个新进程的过程 代码分析 task_struct: struct task ...
- Git push remote rejected {change ### closed}
是因为和关掉的提交对应的Change_id一样导致的. 另一种可能是cherry-pick导致的: 之前提交的时候因为有merge,所以在gerrit服务器上审核的时候,我给abandoned了,因此 ...
- iOS UI基础-18.0 UIView
设置边框 UIView *bgView = [[UIView alloc] init]; bgView.backgroundColor = [UIColor whiteColor]; self.bgV ...
- cocos2d-x JS 纯代码加载播放plist与png动画
var cache = cc.spriteFrameCache; cache.addSpriteFrames(plist, png); var frames = []; for (var i = 1; ...