Files
Athena-Deck/deploy/import_dashboard_history.py

54 lines
2.0 KiB
Python

#!/usr/bin/env python3
"""Copy old Athena dashboard telemetry once, without reading chats or logs.
Run before the first Deck dashboard start. SQLite's backup API safely includes
the source WAL while the old dashboard is still collecting samples.
"""
import argparse
import os
import sqlite3
from pathlib import Path
REQUIRED = {'meta','samples_raw','samples_hourly','slot_samples_raw',
'slot_samples_hourly','token_totals','token_hourly','model_events'}
def import_history(source, target):
source=Path(source)
target=Path(target)
if not source.is_file() or target.exists():
raise ValueError('Quelldatenbank fehlt oder Deck-Ziel existiert bereits; nichts überschrieben.')
target.parent.mkdir(parents=True,exist_ok=True)
old=sqlite3.connect('file:'+str(source)+'?mode=ro',uri=True)
try:
tables={row[0] for row in old.execute("SELECT name FROM sqlite_master WHERE type='table'")}
if not REQUIRED<=tables:raise ValueError('Unbekanntes Dashboard-History-Schema.')
new=sqlite3.connect(target)
try:
old.backup(new)
if new.execute('PRAGMA integrity_check').fetchone()[0]!='ok':
raise ValueError('Kopierte Datenbank ist beschädigt.')
counts={table:new.execute('SELECT COUNT(*) FROM '+table).fetchone()[0]
for table in ('samples_raw','slot_samples_raw','token_hourly','model_events')}
except Exception:
new.close()
target.unlink(missing_ok=True)
raise
finally:
if new: new.close()
target.chmod(0o600)
if os.geteuid()==0:
owner=target.parent.stat()
os.chown(target,owner.st_uid,owner.st_gid)
return counts
finally:
old.close()
if __name__=='__main__':
parser=argparse.ArgumentParser(description=__doc__)
parser.add_argument('source',type=Path)
parser.add_argument('target',type=Path)
args=parser.parse_args()
print(import_history(args.source,args.target))