
3.1 管 理
和Django的其他功能一样,使用Django开发的应用也可以在settings.py中对数据库进行配置。这部分和应用逻辑是解耦的。
Django支持很多数据库的配置,如PostgreSQL(流行的开源关系型数据库)、MySQL、Oracle(甲骨文公司开发的商用数据库)等。本节将以MySQL为例来说明如何使用Django来配置应用使用数据库的行为。
3.1.1 配置
为了描述方便,现在假设您已经有一个可以访问到的MySQL服务,服务的监听IP为127.0.0.1,端口为3306,创建的数据库名为data;同时已经在数据库上建了用户,用户名是yonghu,密码为mima;并且该用户有从所在的网络环境访问data数据库的权限。我们将以此为前提来进行下面的配置。
在Django中配置数据库连接是非常简单的。对于使用django-admin工具创建的项目,settings.py中已经有了DATABASES这个变量,如果没有的话,可直接创建这个变量,这个变量的类型是字典。示例代码如下:

连接配置的使用有一定的顺序,如果配置中定义了OPTIONS,则OPTIONS中定义的连接信息会被优先使用;如果没有定义OPTIONS,则配置中的USER、NAME、PASSWORD、HOST、PORT将会被用到。
DATABASES中定义的数据库的数量不受限制,但必须定义一个名为default的数据库。数据库支持的配置如下:
- ENGINE:这个配置定义数据库后端。Django自带后端支持PostgreSQL、MySQL、SQLite、Oracle。
- HOST:指定要连接的数据库主机地址。这是一个字符串,若为空字符串,则默认主机地址是localhost。若后端使用的数据库是MySQL,则可以指定用于连接的套接字路径,如'/var/run/mysql.sock'。
- NAME:数据库名。
- CONN_MAX_AGE:一个连接的生命周期,单位是秒(s)。该字段设置为0,代表在请求结束的时候断开连接。
- OPTIONS:默认是空字典,用于配置连接到数据库的额外参数。
- PASSWORD:连接数据的密码,默认是空字符串。
- PORT:数据库的端口号,是一个字符串。
- USER:连接数据库的用户名。
3.1.2 连接池
在正式向数据库发起请求前,应用程序需要建立到数据库的连接,建立连接的操作比较耗时,并且会消耗很多资源。
以MySQL为例,其同时支持的连接数量有一个上限,这个值由MySQL的max_connection配置。而应用程序一般会非常频繁地使用数据库来查询数据或者更新数据。Django默认的处理是在新请求进来的时候创建数据库连接,然后在完成请求后关闭连接。
上面列举的情况在每次新请求进来的时候都会发生,当同一时间请求的数量足够多时,应用程序和数据库之间创建的连接数量也会变多。
在大多数情况下,这种连接是网络连接。连接的过程使用了网络套接字,而创建和连接套接字是一个非常耗时的操作,并且在初始化的时候还会涉及查询数据库的操作。在短时间内创建过多连接,会明显降低应用程序的运行速度,并且增加数据库服务的压力。
使用连接池对这种状况有一定的缓解。使用连接池的方法,即将数据库连接放到应用程序的缓存中,在应用程序需要多数据库发出请求时,先从连接池中获取连接,然后使用这个连接请求数据库,在请求完成后,将连接重新放回连接池。连接池的工作方式如图3.1所示。

图3.1 连接池的工作方式
Django在首次进行数据查询时会打开与数据库的连接。这个连接保持在打开状态,并在后续请求中重用。当这个连接存在的时间超过设计的生命周期时,这个连接被关闭,生命周期由CONN_MAX_AGE设置。
Django本身并不支持连接池的配置,要实现连接池,可以使用第三方包,这里使用django_db_polling包。
首先安装这个包,在命令行中执行下面的命令,然后修改wsgi.py文件,添加对连接池的配置:

完成以上修改后,修改CONN_MAX_AGE,一般设置为60。
3.1.3 更改表结构
Django提供的迁移工具可以将对模型所做的更改应用到数据库,修改对应的表单结构和数据。
Django提供了3个常用命令,分别是migrate、makemigration、sqlmigrate。migrate命令负责将迁移应用到数据库;makemigration负责将模型的变动转换成迁移;sqlmigrate会输出应用变动时实际执行的SQL语句。
每个应用都有自己的迁移,因此每个应用的文件夹下都有一个migrations包。可以把迁移看作数据库表结构变更的版本控制系统。makemigrations会将模型的变更打包到单个迁移文件中。migrate命令用于将这个迁移应用到数据库中。
下面来举例说明如何应用迁移,以第2章的商品应用为例来为Product模型建立迁移,在命令行中执行以下命令:

上面的命令会扫描商品应用中的模型,与当前包含在迁移文件中的版本进行比较,然后生成一个新的迁移,迁移的内容放在0001_inital.py文件中。
接下来验证一下迁移时实际执行的SQL语句,在命令行中执行命令:

可以看到,执行的SQL语句和预期的一致。一般来说,企业内部都会有专业的DBA来处理数据表的创建和更改,我们通过sqlmigrate命令得到要创建的SQL语句,然后将该SQL语句提交给DBA执行即可。
也有一些情况需要我们手动去创建数据库表,如创建本地的开发环境数据库表,这时就可以用migrate命令来创建表。命令如下:

如果想验证迁移之后的结果,则可以通过MySQL命令行客户端执行相应命令,查看新建的表结构。以刚创建的product_product表为例,命令如下:
