We do not want to upload the real password a username to a public repository. Instead, set up a local .env
with
USER=<username>
PASSWORD=<password>
DATABASE_NAME=<db>
PORT="5432"
This .env
is in the .gitignore
so is never committed to the public repository. Then, create a config.py
file with a Pydantic Settings class.
from pydantic_settings import BaseSettings, SettingsConfigDict
class DatabaseSettings(BaseSettings):
user: str
password: str
database_name: str
port: str = "5432"
model_config = SettingsConfigDict(
env_file=find_dotenv(usecwd=True), # default behaviour is only to search cwd
env_file_encoding="utf-8", # handle special characters in passwords
extra="ignore",
)
We can then call these settings to connect to the database.
@lru_cache
def get_db_settings():
return DatabaseSettings()
conf = get_db_settings()
db_url = f"postgresql://{conf.user}:{conf.password}@localhost:{conf.port}/{conf.database_name}"
engine = create_engine(db_url)
def init_db():
SQLModel.metadata.create_all(engine)
def get_session():
with Session(engine) as session:
yield session
Using lru_cache
means these variables are only read once from disk.
If the variables are required in a pipeline (for example, during testing), then these environment variables in the .env
must be added as CI/CD variables in pipeline settings.