Skip to content

Commit 32ab6dd

Browse files
patrick91tiangolo
andauthored
♻️ Migrate to DATABASE_URL instead of separate variables (#2184)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
1 parent cf1548a commit 32ab6dd

6 files changed

Lines changed: 18 additions & 31 deletions

File tree

.env

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,5 @@ SMTP_TLS=False
1414
SMTP_PORT=1025
1515

1616
# Postgres
17-
POSTGRES_SERVER=localhost
18-
POSTGRES_DB=app
19-
POSTGRES_USER=postgres
2017
POSTGRES_PASSWORD=changethis
18+
DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@localhost:5432/app

backend/app/alembic/env.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232

3333
def get_url():
34-
return str(settings.SQLALCHEMY_DATABASE_URI)
34+
return str(settings.DATABASE_URL)
3535

3636

3737
def run_migrations_offline():

backend/app/core/config.py

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
HttpUrl,
77
PostgresDsn,
88
computed_field,
9+
field_validator,
910
model_validator,
1011
)
1112
from pydantic_settings import BaseSettings, SettingsConfigDict
@@ -27,23 +28,16 @@ class Settings(BaseSettings):
2728

2829
PROJECT_NAME: str
2930
SENTRY_DSN: HttpUrl | None = None
30-
POSTGRES_SERVER: str
31-
POSTGRES_PORT: int = 5432
32-
POSTGRES_USER: str
33-
POSTGRES_PASSWORD: str = ""
34-
POSTGRES_DB: str = ""
31+
DATABASE_URL: PostgresDsn
3532

36-
@computed_field # type: ignore[prop-decorator]
37-
@property
38-
def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn:
39-
return PostgresDsn.build(
40-
scheme="postgresql+psycopg",
41-
username=self.POSTGRES_USER,
42-
password=self.POSTGRES_PASSWORD,
43-
host=self.POSTGRES_SERVER,
44-
port=self.POSTGRES_PORT,
45-
path=self.POSTGRES_DB,
46-
)
33+
@field_validator("DATABASE_URL", mode="before")
34+
@classmethod
35+
def _use_psycopg_driver(cls, value: str | PostgresDsn) -> str:
36+
database_url = str(value)
37+
for scheme in ("postgres://", "postgresql://"):
38+
if database_url.startswith(scheme):
39+
return database_url.replace(scheme, "postgresql+psycopg://", 1)
40+
return database_url
4741

4842
SMTP_TLS: bool = True
4943
SMTP_SSL: bool = False
@@ -85,7 +79,8 @@ def _check_default_secret(self, var_name: str, value: str | None) -> None:
8579
@model_validator(mode="after")
8680
def _enforce_non_default_secrets(self) -> Self:
8781
self._check_default_secret("SECRET_KEY", self.SECRET_KEY)
88-
self._check_default_secret("POSTGRES_PASSWORD", self.POSTGRES_PASSWORD)
82+
for host in self.DATABASE_URL.hosts():
83+
self._check_default_secret("DATABASE_URL password", host["password"])
8984
self._check_default_secret(
9085
"FIRST_SUPERUSER_PASSWORD", self.FIRST_SUPERUSER_PASSWORD
9186
)

backend/app/core/db.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from app.core.config import settings
55
from app.models import User, UserCreate
66

7-
engine = create_engine(str(settings.SQLALCHEMY_DATABASE_URI))
7+
engine = create_engine(str(settings.DATABASE_URL))
88

99

1010
# make sure all SQLModel models are imported (app.models) before initializing DB

compose.yml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ services:
2020
db:
2121
image: postgres:18
2222
healthcheck:
23-
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
23+
test: ["CMD-SHELL", "pg_isready -U postgres -d app"]
2424
interval: 10s
2525
retries: 5
2626
start_period: 30s
@@ -29,8 +29,7 @@ services:
2929
- app-db-data:/var/lib/postgresql
3030
environment:
3131
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?Variable not set}
32-
- POSTGRES_USER=${POSTGRES_USER:?Variable not set}
33-
- POSTGRES_DB=${POSTGRES_DB:?Variable not set}
32+
- POSTGRES_DB=app
3433

3534
adminer:
3635
image: adminer
@@ -62,10 +61,7 @@ services:
6261
SMTP_USER: ${SMTP_USER:-}
6362
SMTP_PASSWORD: ${SMTP_PASSWORD:-}
6463
EMAILS_FROM_EMAIL: ${EMAILS_FROM_EMAIL}
65-
POSTGRES_SERVER: db
66-
POSTGRES_DB: ${POSTGRES_DB:?Variable not set}
67-
POSTGRES_USER: ${POSTGRES_USER:?Variable not set}
68-
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Variable not set}
64+
DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD:?Variable not set}@db:5432/app
6965
SENTRY_DSN: ${SENTRY_DSN:-}
7066

7167
healthcheck:

deployment.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@ You can set several other environment variables:
8080
* `SMTP_USER`: The SMTP server user to send emails.
8181
* `SMTP_PASSWORD`: The SMTP server password to send emails.
8282
* `EMAILS_FROM_EMAIL`: The email account to send emails from.
83-
* `POSTGRES_USER`: The Postgres user, you can leave the default.
84-
* `POSTGRES_DB`: The database name to use for this application. You can leave the default of `app`.
8583
* `SENTRY_DSN`: The DSN for Sentry, if you are using it.
8684

8785
## GitHub Actions Environment Variables

0 commit comments

Comments
 (0)