FastAPI集成Alembic时Pydantic BaseSettings无法读取.env文件
解决FastAPI+Alembic集成时Pydantic BaseSettings读取.env的路径冲突问题
问题根源在于:运行main.py时当前工作目录是my-app,执行Alembic命令时工作目录是my-app/alembic,导致.env的相对路径无法同时适配两种场景;直接用os.path.abspath("../../.env")也无效——因为该方法是基于当前工作目录计算路径,而非配置文件本身的位置。
以下是两种可靠解决方案:
方案1:基于配置文件位置计算.env绝对路径(推荐)
利用__file__获取config.py的绝对路径,以此为基准向上追溯到my-app目录,再拼接.env路径。这种方式不受执行时工作目录影响,通用性最强。
修改config.py代码:
import os from functools import lru_cache from pydantic_settings import BaseSettings # 从config.py的位置向上三级,定位到my-app根目录 BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) # 拼接.env的绝对路径 ENV_FILE_PATH = os.path.join(BASE_DIR, ".env") class Settings(BaseSettings): APP_NAME: str = "AppName" SQLALCHEMY_URL: str ENVIRONMENT: str class Config: env_file = ENV_FILE_PATH @lru_cache() def get_settings(): return Settings()
如果习惯用pathlib(写法更简洁),可以替换路径计算部分:
from pathlib import Path BASE_DIR = Path(__file__).parent.parent.parent # 从core目录向上两级到my-app根目录 ENV_FILE_PATH = BASE_DIR / ".env"
方案2:在Alembic的env.py中手动加载.env
如果不想修改config.py,可以在Alembic的配置文件中提前加载.env,确保执行Alembic命令时环境变量已被读取。
修改alembic/env.py,在开头添加以下代码:
import os from dotenv import load_dotenv # 从alembic目录向上一级,定位到my-app根目录的.env文件 load_dotenv(os.path.join(os.path.dirname(__file__), "../.env")) # 后续正常导入你的配置模块 from project.core.config import get_settings
注意:此方法需要确保已安装python-dotenv包,若未安装可执行pip install python-dotenv。
内容的提问来源于stack exchange,提问作者Risker
相关产品推荐
相关产品推荐

