2025-08-13 18:05:26 +02:00

114 lines
4.5 KiB
Python

#!/usr/bin/env python3
"""
Database migration script for IoT device fields
Adds new columns to support LILYGO T-A7670G device data
"""
import os
import sys
from sqlalchemy import create_engine, text
from sqlalchemy.exc import OperationalError
# Add the app directory to path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'app'))
from app.core.config import settings
def run_migration():
"""Run database migration to add new IoT device fields"""
engine = create_engine(str(settings.DATABASE_URL))
# Migration queries
migrations = [
# Add new columns to telemetry table
"ALTER TABLE telemetry ADD COLUMN IF NOT EXISTS gps_fixed BOOLEAN DEFAULT FALSE",
"ALTER TABLE telemetry ADD COLUMN IF NOT EXISTS battery_voltage FLOAT",
"ALTER TABLE telemetry ADD COLUMN IF NOT EXISTS humidity FLOAT",
"ALTER TABLE telemetry ADD COLUMN IF NOT EXISTS solar_voltage FLOAT",
"ALTER TABLE telemetry ADD COLUMN IF NOT EXISTS device_timestamp TIMESTAMP WITH TIME ZONE",
# Add comments for new columns
"COMMENT ON COLUMN telemetry.gps_fixed IS 'GPS fix status from IoT device'",
"COMMENT ON COLUMN telemetry.battery_voltage IS 'Actual battery voltage from IoT device'",
"COMMENT ON COLUMN telemetry.humidity IS 'Humidity percentage from IoT device'",
"COMMENT ON COLUMN telemetry.solar_voltage IS 'Solar panel voltage from IoT device'",
"COMMENT ON COLUMN telemetry.device_timestamp IS 'Timestamp from IoT device'",
]
print("Starting database migration for IoT device fields...")
try:
with engine.connect() as conn:
for i, migration in enumerate(migrations, 1):
try:
print(f"Running migration {i}/{len(migrations)}: {migration[:50]}...")
conn.execute(text(migration))
conn.commit()
print(f"✓ Migration {i} completed successfully")
except OperationalError as e:
if "already exists" in str(e) or "column already exists" in str(e):
print(f"⚠ Migration {i} skipped - column already exists")
else:
print(f"✗ Migration {i} failed: {e}")
raise
except Exception as e:
print(f"✗ Migration {i} failed: {e}")
raise
print("✓ All migrations completed successfully!")
print("\nNew IoT device fields added:")
print("- gps_fixed: GPS fix status boolean")
print("- battery_voltage: Raw battery voltage")
print("- humidity: Humidity percentage")
print("- solar_voltage: Solar panel voltage")
print("- device_timestamp: Device timestamp")
except Exception as e:
print(f"✗ Migration failed: {e}")
print("\nThis is normal if you're starting with a fresh database.")
print("The new fields will be created automatically when the app starts.")
return False
return True
def check_migration_needed():
"""Check if migration is needed by testing for new columns"""
engine = create_engine(str(settings.DATABASE_URL))
try:
with engine.connect() as conn:
# Check if telemetry table exists and has new columns
result = conn.execute(text("""
SELECT column_name
FROM information_schema.columns
WHERE table_name = 'telemetry'
AND column_name IN ('gps_fixed', 'battery_voltage', 'humidity', 'solar_voltage', 'device_timestamp')
"""))
existing_columns = [row[0] for row in result]
needed_columns = ['gps_fixed', 'battery_voltage', 'humidity', 'solar_voltage', 'device_timestamp']
missing_columns = [col for col in needed_columns if col not in existing_columns]
if missing_columns:
print(f"Migration needed. Missing columns: {missing_columns}")
return True
else:
print("✓ All IoT device fields already present in database")
return False
except Exception as e:
print(f"Could not check migration status: {e}")
print("Assuming migration is needed...")
return True
if __name__ == "__main__":
print("IoT Device Database Migration Tool")
print("=" * 40)
if check_migration_needed():
run_migration()
else:
print("No migration needed.")