#!/usr/bin/env python3 """ Seed reference data into the database Loads airport and aircraft data from CSV files """ import os import csv import sys from pathlib import Path from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from app.core.config import settings from app.models.ppr import Airport, Aircraft def load_airports(db, csv_path): """Load airport data from CSV""" if not os.path.exists(csv_path): print(f" ⚠ Airport data file not found: {csv_path}") return 0 # Check if data already exists existing_count = db.query(Airport).count() if existing_count > 0: print(f" ⚠ Airport data already exists ({existing_count} records), skipping") return existing_count print(f" Loading airports from {csv_path}...") loaded = 0 batch = [] with open(csv_path, 'r', encoding='utf-8') as f: reader = csv.DictReader(f) for row in reader: airport = Airport( icao=row['icao'], iata=row.get('iata') if row.get('iata') else None, name=row['name'], country=row['country'] ) batch.append(airport) loaded += 1 # Commit in batches of 1000 if len(batch) >= 1000: db.bulk_save_objects(batch) db.commit() batch = [] print(f" Loaded {loaded} airports...", end='\r') # Commit remaining if batch: db.bulk_save_objects(batch) db.commit() print(f" ✓ Loaded {loaded} airport records" + " " * 20) return loaded def load_aircraft(db, csv_path): """Load aircraft data from CSV""" if not os.path.exists(csv_path): print(f" ⚠ Aircraft data file not found: {csv_path}") return 0 # Check if data already exists existing_count = db.query(Aircraft).count() if existing_count > 0: print(f" ⚠ Aircraft data already exists ({existing_count} records), skipping") return existing_count print(f" Loading aircraft from {csv_path}...") loaded = 0 batch = [] with open(csv_path, 'r', encoding='utf-8') as f: reader = csv.DictReader(f) for row in reader: aircraft = Aircraft( icao24=row.get('icao24') if row.get('icao24') else None, registration=row.get('registration') if row.get('registration') else None, manufacturer_icao=row.get('manufacturericao') if row.get('manufacturericao') else None, type_code=row.get('typecode') if row.get('typecode') else None, manufacturer_name=row.get('manufacturername') if row.get('manufacturername') else None, model=row.get('model') if row.get('model') else None ) batch.append(aircraft) loaded += 1 # Commit in batches of 1000 if len(batch) >= 1000: db.bulk_save_objects(batch) db.commit() batch = [] print(f" Loaded {loaded} aircraft...", end='\r') # Commit remaining if batch: db.bulk_save_objects(batch) db.commit() print(f" ✓ Loaded {loaded} aircraft records" + " " * 20) return loaded def main(): """Main seeding function""" print("Starting data seeding process...") try: # Create database connection engine = create_engine(settings.database_url) Session = sessionmaker(bind=engine) db = Session() # Determine CSV paths - check multiple locations base_paths = [ Path('/app/../db-init'), # Docker mounted volume Path('/app/db-init'), # If copied into container Path('./db-init'), # Current directory Path('../db-init'), # Parent directory ] airport_csv = None aircraft_csv = None for base in base_paths: if base.exists(): potential_airport = base / 'airports_data_clean.csv' potential_aircraft = base / 'aircraft_data.csv' if potential_airport.exists() and not airport_csv: airport_csv = str(potential_airport) if potential_aircraft.exists() and not aircraft_csv: aircraft_csv = str(potential_aircraft) if airport_csv and aircraft_csv: break # Load data airports_loaded = 0 aircraft_loaded = 0 if airport_csv: airports_loaded = load_airports(db, airport_csv) else: print(" ⚠ No airport CSV file found") if aircraft_csv: aircraft_loaded = load_aircraft(db, aircraft_csv) else: print(" ⚠ No aircraft CSV file found") db.close() print("") print(f"Seeding complete:") print(f" Airports: {airports_loaded:,}") print(f" Aircraft: {aircraft_loaded:,}") return 0 except Exception as e: print(f"✗ Error during seeding: {e}") import traceback traceback.print_exc() return 1 if __name__ == "__main__": sys.exit(main())