41 lines
1.1 KiB
Python
41 lines
1.1 KiB
Python
import os
|
|
|
|
from sqlalchemy import create_engine
|
|
from sqlalchemy.engine import URL
|
|
from sqlalchemy.orm import DeclarativeBase, Session, sessionmaker
|
|
|
|
|
|
def build_database_url() -> URL | str:
|
|
"""Prefer DATABASE_URL; otherwise build a safely escaped URL from parts.
|
|
|
|
Passwords are passed as URL components (not string interpolation), so
|
|
characters like '@', ':', '/', '#' and '%' cannot corrupt the hostname.
|
|
"""
|
|
database_url = os.environ.get("DATABASE_URL")
|
|
if database_url:
|
|
return database_url
|
|
return URL.create(
|
|
"postgresql+psycopg",
|
|
username=os.environ.get("POSTGRES_USER", "time_track"),
|
|
password=os.environ.get("POSTGRES_PASSWORD", ""),
|
|
host=os.environ.get("POSTGRES_HOST", "localhost"),
|
|
port=int(os.environ.get("POSTGRES_PORT", "5432")),
|
|
database=os.environ.get("POSTGRES_DB", "time_track"),
|
|
)
|
|
|
|
|
|
engine = create_engine(build_database_url(), pool_pre_ping=True)
|
|
SessionLocal = sessionmaker(bind=engine, autocommit=False, autoflush=False)
|
|
|
|
|
|
class Base(DeclarativeBase):
|
|
pass
|
|
|
|
|
|
def get_db():
|
|
db: Session = SessionLocal()
|
|
try:
|
|
yield db
|
|
finally:
|
|
db.close()
|