db_dialect.py 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. """Database dialect helpers for SQLite/PostgreSQL dual support.
  2. Bambuddy defaults to SQLite (zero-config). When DATABASE_URL points to PostgreSQL,
  3. these helpers ensure dialect-specific operations use the correct SQL.
  4. """
  5. from sqlalchemy import func, text
  6. def is_postgres() -> bool:
  7. """Check if using PostgreSQL based on DATABASE_URL."""
  8. from backend.app.core.config import settings
  9. return settings.database_url.startswith("postgresql")
  10. def is_sqlite() -> bool:
  11. """Check if using SQLite based on DATABASE_URL."""
  12. from backend.app.core.config import settings
  13. return settings.database_url.startswith("sqlite")
  14. async def upsert_setting(db, model, key: str, value: str):
  15. """Dialect-aware INSERT ... ON CONFLICT UPDATE for the Settings table."""
  16. if is_postgres():
  17. from sqlalchemy.dialects.postgresql import insert as pg_insert
  18. stmt = pg_insert(model).values(key=key, value=value)
  19. stmt = stmt.on_conflict_do_update(
  20. index_elements=["key"],
  21. set_={"value": value, "updated_at": func.now()},
  22. )
  23. else:
  24. from sqlalchemy.dialects.sqlite import insert as sqlite_insert
  25. stmt = sqlite_insert(model).values(key=key, value=value)
  26. stmt = stmt.on_conflict_do_update(
  27. index_elements=["key"],
  28. set_={"value": value, "updated_at": func.now()},
  29. )
  30. await db.execute(stmt)
  31. async def run_pragma(conn, pragma_sql: str):
  32. """Run a PRAGMA statement only on SQLite (no-op on PostgreSQL)."""
  33. if is_sqlite():
  34. await conn.execute(text(pragma_sql))