66 HttpUrl ,
77 PostgresDsn ,
88 computed_field ,
9+ field_validator ,
910 model_validator ,
1011)
1112from 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 )
0 commit comments