I faced the same problem. I need to connect to two different databases using, of course, different credentials. I would like to have only one BaseSettings
class and reuse it with different env_prefixes
.
I came up with a fairly simple solution.
"""Settings"""
from pathlib import Path
from typing import Literal
from pydantic_settings import BaseSettings
from pydantic import Field
from dotenv import load_dotenv
load_dotenv(Path('./.env'))
class DBConnectionSettings(BaseSettings):
"""Database settings for database"""
def __init__(self, env_prefix: Literal['db_from_', 'db_to_']):
self.model_config['env_prefix'] = env_prefix
super().__init__()
host: str = Field(..., description="Host address of database")
name: str = Field(..., description="Name of database")
port: int = Field(3306, description="Port at host")
driver: str = Field("mysqlconnector", description="Database driver")
user: str = Field(..., description="Database user name")
password: str = Field(..., description="Password for db user")
# Call the settings like:
db_from = DBConnectionSettings('db_from_')
print(db_from)
db_to = DBConnectionSettings('db_to_')
print(db_to)
As an example, my .env file is structured as follows:
db_from_host=localhost
db_from_name=db1
db_from_user=user1
db_from_password=secret
db_to_host=localhost
db_to_name=db2
db_to_user=user2
db_to_password=reallyasecret
For your task, the dictionary self.model_config['extra']
can also be set. I suspect this solution is not perfect, as it bypasses any type checking performed by Pydantic's SettingsConfigDict
and ConfigDict
classes. Please urgently consider this.