Django中处理多数据库场景
在Django中处理多数据库场景时,不需要每次请求都手动创建、断开连接,Django内置了数据库连接管理机制,会自动处理连接的创建、复用和释放,你只需要正确配置和指定目标数据库即可。
具体处理方式如下:
1. 先配置多数据库连接
在settings.py
中配置所有需要用到的数据库,例如:
DATABASES = {# 默认数据库(可能不是业务用的)'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'default_db','USER': 'root','PASSWORD': '123456','HOST': 'localhost','PORT': '3306',},# 业务数据库1'biz_db1': {'ENGINE': 'django.db.backends.mysql','NAME': 'biz_db1','USER': 'root','PASSWORD': '123456','HOST': '192.168.1.100','PORT': '3306',},# 业务数据库2'biz_db2': {'ENGINE': 'django.db.backends.postgresql','NAME': 'biz_db2','USER': 'postgres','PASSWORD': '123456','HOST': '192.168.1.101','PORT': '5432',}
}
2. 在代码中指定使用的数据库
需要操作非默认数据库时,通过以下方式指定目标数据库,Django会自动管理其连接:
-
方式1:ORM操作时指定数据库
对模型查询/操作时,使用using(数据库别名)
指定:# 查询biz_db1中的数据 result = MyModel.objects.using('biz_db1').filter(xxx=xxx)# 保存数据到biz_db2 obj = MyModel(xxx=xxx) obj.save(using='biz_db2')
-
方式2:执行原始SQL时指定数据库
通过connections[数据库别名]
获取指定数据库的连接,再创建游标执行SQL:from django.db import connectionsdef query_biz_db1(sql):# 获取biz_db1的连接(Django会自动创建,无需手动connect)with connections['biz_db1'].cursor() as cursor:cursor.execute(sql)return cursor.fetchall() # 执行SQL并返回结果# with上下文结束后,游标自动关闭,连接由Django管理(不会立即断开,会复用)
3. Django对连接的自动管理机制
Django会在第一次需要数据库连接时(如执行SQL、ORM操作)自动创建连接,并将连接关联到当前请求的生命周期中:
- 同一请求内多次操作同一数据库,会复用已创建的连接,不会重复创建;
- 请求结束后(无论成功/失败),Django会自动关闭连接(或放回连接池,若配置了连接池);
- 若长时间没有请求,连接会在达到数据库的
wait_timeout
后自动断开,下次请求时会重新创建。
4. 优化建议(高并发场景)
如果业务中频繁操作多数据库,可通过连接池优化连接创建开销(默认Django没有连接池,每次新请求可能创建新连接):
使用第三方库django-db-connection-pool
,为每个数据库配置连接池,减少频繁创建/断开连接的性能损耗。
安装后在settings.py
中配置:
# 配置连接池
DATABASES = {'biz_db1': {'ENGINE': 'dj_db_conn_pool.backends.mysql', # 使用连接池引擎'NAME': 'biz_db1',# ... 其他配置同上 ...'POOL_OPTIONS': { # 连接池参数'POOL_SIZE': 20, # 池大小'MAX_OVERFLOW': 10, # 最大溢出连接数'RECYCLE': 300, # 连接回收时间(秒)}}
}
总结
- 无需手动
创建/断开
连接,Django会自动管理多数据库的连接生命周期; - 通过
using()
(ORM)或connections[别名]
(原始SQL)指定目标数据库即可; - 高并发场景下,建议配置连接池减少性能损耗。
在Django中同时配置MySQL和Oracle数据库非常简单,只需在settings.py
的DATABASES
配置项中分别定义两种数据库的连接信息即可。以下是具体的配置示例:
# settings.pyDATABASES = {# 默认数据库(可以是MySQL或Oracle,根据实际情况选择)'default': {'ENGINE': 'django.db.backends.mysql', # MySQL引擎'NAME': 'mysql_default_db', # 数据库名称'USER': 'mysql_user', # 用户名'PASSWORD': 'mysql_password', # 密码'HOST': 'mysql_host', # 数据库主机地址'PORT': '3306', # MySQL默认端口'OPTIONS': {'charset': 'utf8mb4', # 字符集'connect_timeout': 10, # 连接超时时间(秒)},},# Oracle数据库配置'oracle_db': {'ENGINE': 'django.db.backends.oracle', # Oracle引擎'NAME': '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle_host)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl)))', # Oracle连接串'USER': 'oracle_user', # Oracle用户名'PASSWORD': 'oracle_password', # 密码'OPTIONS': {'threaded': True, # 启用线程模式'use_returning_into': False, # 处理返回值的兼容性设置},},# 可以添加更多数据库配置...# 'another_mysql_db': { ... }
}# 可选:配置数据库路由(如果需要自动决定模型使用哪个数据库)
DATABASE_ROUTERS = [# 'myapp.routers.MyRouter', # 自定义路由类的路径
]
配置说明:
-
MySQL配置项:
ENGINE
:指定为django.db.backends.mysql
- 基本连接信息包括
NAME
(数据库名)、USER
、PASSWORD
、HOST
、PORT
OPTIONS
中可以设置字符集、连接超时等参数
-
Oracle配置项:
ENGINE
:指定为django.db.backends.oracle
NAME
:使用Oracle连接串格式,包含主机、端口和服务名- Oracle默认端口是1521
- 注意Oracle的用户权限和表空间设置
使用方式:
在代码中使用特定数据库时,只需指定数据库别名即可:
# 使用ORM操作时
# 查询Oracle数据库
oracle_data = MyModel.objects.using('oracle_db').all()# 保存到MySQL默认数据库
my_obj = MyModel(...)
my_obj.save() # 默认使用'default'数据库# 执行原始SQL
from django.db import connections# 操作Oracle数据库
with connections['oracle_db'].cursor() as cursor:cursor.execute("SELECT * FROM oracle_table")result = cursor.fetchall()
注意事项:
-
确保已安装相应的数据库驱动:
- MySQL:
pip install mysqlclient
或pip install pymysql
- Oracle:
pip install cx_Oracle
- MySQL:
-
如果使用
pymysql
作为MySQL驱动,需要在项目的__init__.py
中添加:import pymysql pymysql.install_as_MySQLdb()
-
对于Oracle,可能需要配置
ORACLE_HOME
环境变量并安装Oracle客户端
这种配置方式可以让你在同一个Django项目中无缝切换和使用MySQL与Oracle数据库,Django会自动管理连接的创建和释放。