import os import urllib.parse from dotenv import load_dotenv load_dotenv() def quote(value: str) -> str: return urllib.parse.quote_plus(value or '') class Config: SQLALCHEMY_TRACK_MODIFICATIONS = False DEBUG = False TESTING = False DB_BACKEND = os.getenv('DB_BACKEND', 'sqlite').lower() DB_WINDOWS_AUTH = os.getenv('DB_WINDOWS_AUTH', 'false').strip().lower() in ['true', '1', 'yes'] DB_USER = os.getenv('DB_USER', '') DB_PASSWORD = os.getenv('DB_PASSWORD', '') DB_HOST = os.getenv('DB_HOST', 'localhost') DB_PORT = os.getenv('DB_PORT', '') DB_NAME = os.getenv('DB_NAME', 'app.db') # default SQLite filename BASE_DIR = os.path.abspath(os.path.dirname(__file__)) SQLALCHEMY_DATABASE_URI = None # This will definitely be set below if DB_BACKEND == 'mssql': driver = os.getenv('DB_DRIVER', 'ODBC Driver 17 for SQL Server') quoted_driver = quote(driver) if DB_WINDOWS_AUTH: SQLALCHEMY_DATABASE_URI = ( f"mssql+pyodbc://@{DB_HOST}/{DB_NAME}?driver={quoted_driver}&Trusted_Connection=yes" ) else: SQLALCHEMY_DATABASE_URI = ( f"mssql+pyodbc://{quote(DB_USER)}:{quote(DB_PASSWORD)}@{DB_HOST}:{DB_PORT or '1433'}/{DB_NAME}" f"?driver={quoted_driver}" ) elif DB_BACKEND == 'postgres': SQLALCHEMY_DATABASE_URI = ( f"postgresql://{quote(DB_USER)}:{quote(DB_PASSWORD)}@{DB_HOST}:{DB_PORT or '5432'}/{DB_NAME}" ) elif DB_BACKEND in ['mariadb', 'mysql']: SQLALCHEMY_DATABASE_URI = ( f"mysql+pymysql://{quote(DB_USER)}:{quote(DB_PASSWORD)}@{DB_HOST}:{DB_PORT or '3306'}/{DB_NAME}" ) elif DB_BACKEND == 'sqlite': if DB_NAME == ':memory:': SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:' else: full_path = os.path.join(BASE_DIR, DB_NAME) SQLALCHEMY_DATABASE_URI = f"sqlite:///{full_path}" else: raise ValueError( f"Unsupported DB_BACKEND: {DB_BACKEND}. " "Supported backends: mssql, postgres, mariadb, mysql, sqlite." ) # Optional: confirm config during development print(f"Using database URI: {SQLALCHEMY_DATABASE_URI}")