Django执行makemigrations时触发KeyError: 'DB_NAME'问题排查
问题背景
我将所有密钥和数据库参数存储在dev.env文件中,项目拥有base、dev、prod三个配置文件:base配置使用SQLite数据库,dev配置需要连接PostgreSQL。
dev配置文件中加载环境变量的代码:
from dotenv import load_dotenv load_dotenv(os.environ.get('ENV_CONFIG', ''))
dev配置文件中重写的数据库设置:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.environ['DB_NAME'], 'USER': os.environ['DB_USER'], 'PASSWORD': os.environ['DB_PASS'], 'HOST': os.environ['DB_HOST'], 'PORT': os.environ['DB_PORT'], } }
执行命令./manage.py makemigrations --settings=app.settings.dev时出现以下错误:
File "/Users/admin/Desktop/Programming/Python/UkranianFunds/src/app/settings/dev.py", line 35, in <module> 'NAME': os.environ['DB_NAME'], File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/os.py", line 679, in __getitem__ raise KeyError(key) from None KeyError: 'DB_NAME'
已确认DB_NAME存在于dev.env文件中且能正常打印,以下是可能的排查方向:
可能的原因及解决方法
ENV_CONFIG环境变量未正确传递:
你通过os.environ.get('ENV_CONFIG', '')指定env文件路径,但如果执行命令时未设置这个变量,load_dotenv会接收空字符串,相当于未加载任何env文件。执行命令时需显式传递ENV_CONFIG指向dev.env的绝对路径,示例:ENV_CONFIG=/Users/admin/Desktop/Programming/Python/UkranianFunds/src/dev.env ./manage.py makemigrations --settings=app.settings.devenv文件路径为相对路径导致加载失败:
若ENV_CONFIG设置的是相对路径,可能因执行命令的工作目录与文件实际位置不匹配,导致dotenv找不到文件。建议始终使用绝对路径指定env文件。配置文件加载顺序干扰:
若dev配置文件先导入了base配置,而base配置中也有加载env的逻辑,可能会覆盖或干扰dev的环境变量加载。检查dev.py的导入顺序,确保load_dotenv代码在数据库配置之前执行,且未被其他配置的加载逻辑影响。dev.env文件格式错误:
检查dev.env中的键值对格式,避免等号两侧添加空格(如错误格式DB_NAME = my_db,正确格式DB_NAME=my_db),部分dotenv版本对空格敏感,可能导致变量解析失败。虚拟环境中未安装python-dotenv:
若项目使用了虚拟环境,确认虚拟环境已激活,且通过pip install python-dotenv安装了依赖。如果dotenv仅安装在全局Python环境中,虚拟环境内的代码会无法加载该模块,导致环境变量加载失败。dotenv加载优先级问题:
dotenv默认不会覆盖已存在的系统环境变量,但如果加载失败时,os.environ会读取系统变量。可以尝试添加override=True参数强制覆盖,确保加载本地env文件的变量:load_dotenv(os.environ.get('ENV_CONFIG', ''), override=True)
内容的提问来源于stack exchange,提问作者idunskyi

