如何设置Django数据库超时时间 避免AWS Lambda触发502错误
Django 配置SQL执行超时的实现方案
当数据库服务不可达或连接异常时,默认配置下数据库驱动会持续等待响应,不会主动抛出异常,最终触发AWS Lambda的300秒超时返回502,可通过以下成熟方案配置短超时,让异常能被正常捕获:
方案一:全局配置数据库超时(推荐)
直接在Django项目的settings.py中修改DATABASES配置,通过数据库驱动的OPTIONS参数设置连接、读写超时,不同数据库配置参数有区别:
- MySQL(pymysql/mysqlclient驱动)
超时参数单位为秒,可根据业务容忍度设置为3~10秒:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'db_name', 'USER': 'db_user', 'PASSWORD': 'db_pass', 'HOST': 'db_host', 'PORT': 3306, 'OPTIONS': { 'connect_timeout': 5, # 建立数据库连接的超时时间 'read_timeout': 5, # 读查询执行超时时间 'write_timeout': 5, # 写操作执行超时时间(mysqlclient 1.4.0+版本支持) } } }
- PostgreSQL(psycopg2驱动)
连接超时单位为秒,SQL执行超时单位为毫秒:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'db_name', 'USER': 'db_user', 'PASSWORD': 'db_pass', 'HOST': 'db_host', 'PORT': 5432, 'OPTIONS': { 'connect_timeout': 5, # 连接超时,单位秒 'options': '-c statement_timeout=5000' # 单条SQL执行超时,此处为5秒 } } }
- SQLite
SQLite为文件型数据库,无网络连接场景,可通过timeout参数设置锁等待超时,单位为秒。
方案二:单查询临时设置超时
如果仅需要对特定接口/查询设置超时,不需要修改全局配置,可在执行查询前通过SQL语句临时设置会话级超时:
- MySQL场景:
from django.db import connection from django.db import OperationalError, InterfaceError try: with connection.cursor() as cursor: # 仅对当前数据库会话生效 cursor.execute("SET SESSION connect_timeout=3, SESSION net_read_timeout=3, SESSION net_write_timeout=3") myuser = MyUser.objects.get(id=user_id) except (OperationalError, InterfaceError) as e: print(e) # 执行后续降级流程
- PostgreSQL场景:
from django.db import connection from django.db import OperationalError, InterfaceError try: with connection.cursor() as cursor: cursor.execute("SET statement_timeout = 3000") # 3秒执行超时 myuser = MyUser.objects.get(id=user_id) except (OperationalError, InterfaceError) as e: print(e) # 执行后续降级流程
注意事项
- 配置超时后,连接失败、查询超时场景下驱动会直接抛出
django.db.OperationalError或InterfaceError,建议明确捕获这两类数据库异常,不要直接用裸Exception捕获,避免误吞其他业务异常。 - 如果在Lambda场景下配置了数据库连接复用,建议同时开启连接有效性校验,避免拿到已断开的死连接阻塞请求。
内容的提问来源于stack exchange,提问作者whitebear
相关产品推荐
相关产品推荐

