mirror of
https://github.com/fastapi/full-stack-fastapi-template.git
synced 2026-11-03 12:29:42 +00:00
♻️ Migrate to DATABASE_URL instead of separate variables (#2184)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user