Flask Web开发入门、进阶与实战
上QQ阅读APP看书,第一时间看更新

4.3 使用Flask-SQLAlchemy管理数据库

SQLAlchemy是一个功能强大的关系型数据库框架,不但提供了高层ORM功能,而且也提供了使用数据库原生SQL的低层功能。在Flask Web程序中,使用Flask-SQLAlchemy扩展可以简化使用SQLAlchemy的步骤,提高开发效率。在本节的内容中,将详细讲解在Flask Web中使用Flask-SQLAlchemy的知识。

4.3.1 Flask-SQLAlchemy基础

在使用Flask-SQLAlchemy之前,需要先使用如下pip命令进行安装。

在使用Flask-SQLAlchemy扩展时,需要使用URL设置要操作的数据库,使用Flask-SQ-LAlchemy连接主流数据库的语法如下。

• MySQL:

• Postgres:

• SQLite(Unix):

• SQLite(Windows):

对上述URL连接的具体说明如下。

• hostname:表示数据库服务器所在的主机,可以是本地主机(localhost),也可以是远程服务器。

• database:表示要连接的数据库名称。

• username和password:表示连接数据库的用户名和密码。

在Flask Web程序中,必须将连接数据库的URL保存到Flask配置对象的SQLALCHEMY_DATABASE_URI键中。在配置对象中可以将SQLALCHEMY_COMMIT_ON_TEARDOWN键的值设置为True,这样在访问请求结束后会自动提交数据库中的变化。

注意:因为SQLite数据库是一个轻量级产品,不需要使用服务器,所以在使用时无须设置URL中的hostname、username和password参数。URL中的参数database是在硬盘的具体保存路径。

4.3.2 定义模型

在软件开发领域中,将在程序中使用的持久化实体称为模型。在Python的ORM中,一个模型对应一个Python类,类中的各个属性分别对应数据库表中的列,这一点和Django框架中的Models类似。假如在程序中需要用到两个数据库表rank和users,那么可以在Python程序中定义模型Rank和User,例如下面的演示代码。

1)类变量__tablename__:用于定义在数据库中使用的数据库表的名字。如果没有定义__tablename__的名字,SQLAlchemy会使用一个没有遵守使用复数形式进行命名约定的默认名字。

2)类变量id、name、users:都是该模型中的属性,对应数据表中的属性成员。

3)db.Column:在类db.Column的构造函数中,其中第一个参数表示数据库列和模型属性的类型,在下面列出了一些常用的列类型以及在模型中使用的Python类型。

• Integer:表示int整数类型,一般是32位。

• SmallInteger:表示取值范围小的int整数类型,一般是16位。

• BigInteger:表示不限制精度的整数类型int或long。

• Float:表示float浮点数类型。

• Numeric:表示Decimal类型。

• String:表示str变长字符串类型。

• Text:表示str变长字符串类型,但是和上面的String类型相比,此类型对较长或不限长度的字符串做了优化。

• Unicode:表示变长Unicode字符串类型。

• UnicodeText:表示变长Unicode字符串类型,但是和上面的Unicode类型相比,对较长或不限长度的字符串做了优化。

• Boolean:表示bool布尔值类型。

• Date:表示datetime.date日期类型。

• Time:表示datetime.time时间类型。

• DateTime:表示datetime.datetime日期和时间类型。

• Interval:表示datetime.timedelta时间间隔类型。

• Enum:表示一组字符串类型。

• PickleType:可以是任何Python对象类型,自动使用Pickle序列化保存的数据。

• LargeBinary:表示二进制文件类型。

另外,在db.Column中还包含了其余的参数,功能是指定属性的配置选项。下面列出了一些经常用到的选项。

• unique:如果将其属性设为True,表示不允许在当前列中出现重复的值,反之为False。

• index:如果将其属性设为True,表示为当前列创建提升查询效率的索引,反之为False。

• nullable:如果将其属性设为True,表示当前列中可以使用空值,反之为False。

• default:为当前列设置一个默认值。

注意:Flask-SQLAlchemy规定,应为每个模型定义主键,这个主键通常被命名为id。

4.3.3 关系

在Flask Web程序中,可以使用关系型数据库把不同表中的行联系起来。图4-5所示的关系图中,展示了用户和角色之间的一种关系。因为一个角色可属于多个用户,而每个用户只能有一个角色,所以在图中展示的只是角色到用户的一对多关系。

图4-5 关系图

在下面的演示代码中,展示了图4-5中的一对多关系在模型类中的表示方法。

在图4-5所示的关系中,添加到模型User中的列rank_id被定义为外键,就是通过这个外键建立起了关系。传递给db.ForeignKey()方法的参数是rank.id,表示此列显示的是表Rank中每一行数据的id值。

上面的方法db.relationship()有两个参数,具体说明如下所示。

• 参数User:在定义类Rank的实例对象后,可以使用属性users表示与角色相关联的用户组成的列表。函数db.relationship()的第一个参数是User,用于表示这个关系的另一端属于哪个模型。

• 参数backref:在模型User中使用Rank属性定义反向关系,可以使用属性Rank代替Rank_id来访问Rank模型,此时获取的是模型对象,而不是外键的值。

在大多数情况下,函数db.relationship()可以独立找到关系中的外键,但是有时无法确定把哪一列作为外键。举个例子,假如在模型User中将两个或两个以上的列定义为模型Rank的外键,那么SQLAlchemy就无法确定应该使用哪一列作为外键,此时需要为函数db.relationship()提供额外的参数来设置使用哪个外键。