Show database engine and version on System Information page

Display the active database backend (SQLite or PostgreSQL) and its
  version in the Database section of the System Info page. SQLite queries
  sqlite_version(), PostgreSQL queries SELECT version() and
  pg_database_size(). Helps users verify which database is in use.
This commit is contained in:
maziggy
2026-04-04 09:05:35 +02:00
parent 15cd4cbb0a
commit 0f0fac9b32
7 changed files with 113 additions and 65 deletions
+1
View File
@@ -8,6 +8,7 @@ All notable changes to Bambuddy will be documented in this file.
- **Optional PostgreSQL Database Support** — Bambuddy can now use an external PostgreSQL database instead of the built-in SQLite. Set the `DATABASE_URL` environment variable (e.g., `postgresql+asyncpg://user:pass@host:5432/bambuddy`) to connect to Postgres. SQLite remains the default when no `DATABASE_URL` is set. All features work with both backends including full-text archive search (FTS5 on SQLite, tsvector+GIN on PostgreSQL), backup/restore (file copy vs pg_dump/pg_restore), health diagnostics, and cross-database restore (import a SQLite backup into PostgreSQL with automatic type conversion and FK handling).
### Improved
- **Database Engine Info on System Page** — The System Information page now shows the active database engine (SQLite or PostgreSQL) and its version in the Database section, making it easy to verify which backend is in use.
- **REST Smart Plug: Separate Power/Energy URLs and Unit Multipliers** ([#472](https://github.com/maziggy/bambuddy/issues/472)) — REST/Webhook smart plugs can now use individual URLs for power and energy data instead of requiring all values in a single status response. Each value falls back to the shared Status URL when no separate URL is configured, so existing setups work without changes. Added power and energy multipliers for unit conversion (e.g., set energy multiplier to `0.001` to convert Wh to kWh). Useful for platforms like ioBroker that expose each data point as a separate API endpoint.
### Fixed
+34 -3
View File
@@ -453,9 +453,38 @@ async def get_system_info(
archive_dir = settings.archive_dir
archive_size = get_directory_size(archive_dir) if archive_dir.exists() else 0
# Database file size
db_path = settings.base_dir / "bambuddy.db"
db_size = db_path.stat().st_size if db_path.exists() else 0
# Database info (engine type, version, size)
from backend.app.core.db_dialect import is_postgres, is_sqlite
db_engine_info: dict = {"engine": "unknown", "version": "unknown"}
db_size = 0
try:
if is_postgres():
from sqlalchemy import text
result = await db.execute(text("SELECT version()"))
pg_version_full = result.scalar() or "unknown"
# e.g. "PostgreSQL 16.2 on x86_64..." → "PostgreSQL 16.2"
pg_version = " ".join(pg_version_full.split()[:2])
result = await db.execute(text("SELECT pg_database_size(current_database())"))
db_size = result.scalar() or 0
db_engine_info = {
"engine": "PostgreSQL",
"version": pg_version,
}
elif is_sqlite():
from sqlalchemy import text
result = await db.execute(text("SELECT sqlite_version()"))
sqlite_ver = result.scalar() or "unknown"
db_path = settings.base_dir / "bambuddy.db"
db_size = db_path.stat().st_size if db_path.exists() else 0
db_engine_info = {
"engine": "SQLite",
"version": f"SQLite {sqlite_ver}",
}
except Exception:
pass
# Disk usage
disk = psutil.disk_usage(str(settings.base_dir))
@@ -475,6 +504,8 @@ async def get_system_info(
"archive_dir": str(archive_dir),
},
"database": {
"engine": db_engine_info["engine"],
"version": db_engine_info["version"],
"archives": archive_count,
"archives_completed": completed_count,
"archives_failed": failed_count,
@@ -30,6 +30,8 @@ const mockSystemInfo = {
archive_dir: '/opt/bambuddy/archives',
},
database: {
engine: 'SQLite',
version: 'SQLite 3.45.1',
archives: 150,
archives_completed: 140,
archives_failed: 8,
+2
View File
@@ -4473,6 +4473,8 @@ export interface SystemInfo {
archive_dir: string;
};
database: {
engine: string;
version: string;
archives: number;
archives_completed: number;
archives_failed: number;
+12
View File
@@ -357,6 +357,18 @@ export function SystemInfoPage() {
{/* Database Stats */}
<Section title={t('system.database', 'Database')} icon={Database}>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<StatCard
icon={Database}
label={t('system.dbEngine', 'Database Engine')}
value={systemInfo.database.engine || 'SQLite'}
/>
<StatCard
icon={Database}
label={t('system.dbVersion', 'Version')}
value={systemInfo.database.version || 'unknown'}
/>
</div>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-4">
<StatCard
icon={Archive}
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -23,7 +23,7 @@
<!-- Splash screens for iOS -->
<link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
<script type="module" crossorigin src="/assets/index-CQTlViGa.js"></script>
<script type="module" crossorigin src="/assets/index-Bexverg5.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BGA3I7Jb.css">
</head>
<body>