♻️ Migrate to DATABASE_URL instead of separate variables (#2184)

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
This commit is contained in:
Patrick Arminio
2026-08-11 18:28:34 +01:00
committed by GitHub
parent cf1548a983
commit 32ab6dd022
6 changed files with 18 additions and 31 deletions
+1 -3
View File
@@ -14,7 +14,5 @@ SMTP_TLS=False
SMTP_PORT=1025 SMTP_PORT=1025
# Postgres # Postgres
POSTGRES_SERVER=localhost
POSTGRES_DB=app
POSTGRES_USER=postgres
POSTGRES_PASSWORD=changethis POSTGRES_PASSWORD=changethis
DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@localhost:5432/app
+1 -1
View File
@@ -31,7 +31,7 @@ target_metadata = SQLModel.metadata
def get_url(): def get_url():
return str(settings.SQLALCHEMY_DATABASE_URI) return str(settings.DATABASE_URL)
def run_migrations_offline(): def run_migrations_offline():
+12 -17
View File
@@ -6,6 +6,7 @@ from pydantic import (
HttpUrl, HttpUrl,
PostgresDsn, PostgresDsn,
computed_field, computed_field,
field_validator,
model_validator, model_validator,
) )
from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic_settings import BaseSettings, SettingsConfigDict
@@ -27,23 +28,16 @@ class Settings(BaseSettings):
PROJECT_NAME: str PROJECT_NAME: str
SENTRY_DSN: HttpUrl | None = None SENTRY_DSN: HttpUrl | None = None
POSTGRES_SERVER: str DATABASE_URL: PostgresDsn
POSTGRES_PORT: int = 5432
POSTGRES_USER: str
POSTGRES_PASSWORD: str = ""
POSTGRES_DB: str = ""
@computed_field # type: ignore[prop-decorator] @field_validator("DATABASE_URL", mode="before")
@property @classmethod
def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn: def _use_psycopg_driver(cls, value: str | PostgresDsn) -> str:
return PostgresDsn.build( database_url = str(value)
scheme="postgresql+psycopg", for scheme in ("postgres://", "postgresql://"):
username=self.POSTGRES_USER, if database_url.startswith(scheme):
password=self.POSTGRES_PASSWORD, return database_url.replace(scheme, "postgresql+psycopg://", 1)
host=self.POSTGRES_SERVER, return database_url
port=self.POSTGRES_PORT,
path=self.POSTGRES_DB,
)
SMTP_TLS: bool = True SMTP_TLS: bool = True
SMTP_SSL: bool = False SMTP_SSL: bool = False
@@ -85,7 +79,8 @@ class Settings(BaseSettings):
@model_validator(mode="after") @model_validator(mode="after")
def _enforce_non_default_secrets(self) -> Self: def _enforce_non_default_secrets(self) -> Self:
self._check_default_secret("SECRET_KEY", self.SECRET_KEY) self._check_default_secret("SECRET_KEY", self.SECRET_KEY)
self._check_default_secret("POSTGRES_PASSWORD", self.POSTGRES_PASSWORD) for host in self.DATABASE_URL.hosts():
self._check_default_secret("DATABASE_URL password", host["password"])
self._check_default_secret( self._check_default_secret(
"FIRST_SUPERUSER_PASSWORD", self.FIRST_SUPERUSER_PASSWORD "FIRST_SUPERUSER_PASSWORD", self.FIRST_SUPERUSER_PASSWORD
) )
+1 -1
View File
@@ -4,7 +4,7 @@ from app import crud
from app.core.config import settings from app.core.config import settings
from app.models import User, UserCreate from app.models import User, UserCreate
engine = create_engine(str(settings.SQLALCHEMY_DATABASE_URI)) engine = create_engine(str(settings.DATABASE_URL))
# make sure all SQLModel models are imported (app.models) before initializing DB # make sure all SQLModel models are imported (app.models) before initializing DB
+3 -7
View File
@@ -20,7 +20,7 @@ services:
db: db:
image: postgres:18 image: postgres:18
healthcheck: healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] test: ["CMD-SHELL", "pg_isready -U postgres -d app"]
interval: 10s interval: 10s
retries: 5 retries: 5
start_period: 30s start_period: 30s
@@ -29,8 +29,7 @@ services:
- app-db-data:/var/lib/postgresql - app-db-data:/var/lib/postgresql
environment: environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?Variable not set} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?Variable not set}
- POSTGRES_USER=${POSTGRES_USER:?Variable not set} - POSTGRES_DB=app
- POSTGRES_DB=${POSTGRES_DB:?Variable not set}
adminer: adminer:
image: adminer image: adminer
@@ -62,10 +61,7 @@ services:
SMTP_USER: ${SMTP_USER:-} SMTP_USER: ${SMTP_USER:-}
SMTP_PASSWORD: ${SMTP_PASSWORD:-} SMTP_PASSWORD: ${SMTP_PASSWORD:-}
EMAILS_FROM_EMAIL: ${EMAILS_FROM_EMAIL} EMAILS_FROM_EMAIL: ${EMAILS_FROM_EMAIL}
POSTGRES_SERVER: db DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD:?Variable not set}@db:5432/app
POSTGRES_DB: ${POSTGRES_DB:?Variable not set}
POSTGRES_USER: ${POSTGRES_USER:?Variable not set}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Variable not set}
SENTRY_DSN: ${SENTRY_DSN:-} SENTRY_DSN: ${SENTRY_DSN:-}
healthcheck: healthcheck:
-2
View File
@@ -80,8 +80,6 @@ You can set several other environment variables:
* `SMTP_USER`: The SMTP server user to send emails. * `SMTP_USER`: The SMTP server user to send emails.
* `SMTP_PASSWORD`: The SMTP server password to send emails. * `SMTP_PASSWORD`: The SMTP server password to send emails.
* `EMAILS_FROM_EMAIL`: The email account to send emails from. * `EMAILS_FROM_EMAIL`: The email account to send emails from.
* `POSTGRES_USER`: The Postgres user, you can leave the default.
* `POSTGRES_DB`: The database name to use for this application. You can leave the default of `app`.
* `SENTRY_DSN`: The DSN for Sentry, if you are using it. * `SENTRY_DSN`: The DSN for Sentry, if you are using it.
## GitHub Actions Environment Variables ## GitHub Actions Environment Variables