fix: update logging messages for database operations and version bump
- Changed logging output for PostgreSQL readiness, schema loading, and migration status to a consistent format using [OK], [FAIL], and [WARN]. - Updated application version to 0.8.14 and modified changelog to reflect recent changes, including a fix for co-trainer backfill logic in the database migration. - Enhanced error handling messages for better clarity during migration processes.
This commit is contained in:
parent
0c044249d9
commit
e69aca51f6
|
|
@ -32,13 +32,13 @@ def wait_for_postgres(max_retries=30):
|
|||
try:
|
||||
conn = get_connection()
|
||||
conn.close()
|
||||
print("✓ PostgreSQL ready")
|
||||
print("[OK] PostgreSQL ready")
|
||||
return True
|
||||
except OperationalError:
|
||||
print(f" Waiting for PostgreSQL... (attempt {i}/{max_retries})")
|
||||
time.sleep(2)
|
||||
|
||||
print(f"✗ PostgreSQL not ready after {max_retries} attempts")
|
||||
print(f"[FAIL] PostgreSQL not ready after {max_retries} attempts")
|
||||
return False
|
||||
|
||||
def check_table_exists(table_name="profiles"):
|
||||
|
|
@ -71,10 +71,10 @@ def load_schema(schema_file="/app/schema.sql"):
|
|||
conn.commit()
|
||||
cur.close()
|
||||
conn.close()
|
||||
print("✓ Schema loaded from schema.sql")
|
||||
print("[OK] Schema loaded from schema.sql")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"✗ Error loading schema: {e}")
|
||||
print(f"[FAIL] Error loading schema: {e}")
|
||||
return False
|
||||
|
||||
def get_profile_count():
|
||||
|
|
@ -146,10 +146,10 @@ def apply_migration(filepath, filename):
|
|||
conn.commit()
|
||||
cur.close()
|
||||
conn.close()
|
||||
print(f" ✓ Applied: {filename}")
|
||||
print(f" [OK] Applied: {filename}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f" ✗ Failed to apply {filename}: {e}")
|
||||
print(f" [FAIL] Failed to apply {filename}: {e}")
|
||||
return False
|
||||
|
||||
def run_migrations(migrations_dir="/app/migrations"):
|
||||
|
|
@ -158,7 +158,7 @@ def run_migrations(migrations_dir="/app/migrations"):
|
|||
import re
|
||||
|
||||
if not os.path.exists(migrations_dir):
|
||||
print("✓ No migrations directory found")
|
||||
print("[OK] No migrations directory found")
|
||||
return True
|
||||
|
||||
# Ensure migration tracking table exists
|
||||
|
|
@ -174,7 +174,7 @@ def run_migrations(migrations_dir="/app/migrations"):
|
|||
migration_files = [f for f in all_files if migration_pattern.match(os.path.basename(f))]
|
||||
|
||||
if not migration_files:
|
||||
print("✓ No migration files found")
|
||||
print("[OK] No migration files found")
|
||||
return True
|
||||
|
||||
# Apply pending migrations
|
||||
|
|
@ -185,7 +185,7 @@ def run_migrations(migrations_dir="/app/migrations"):
|
|||
pending.append((filepath, filename))
|
||||
|
||||
if not pending:
|
||||
print(f"✓ All {len(applied)} migrations already applied")
|
||||
print(f"[OK] All {len(applied)} migrations already applied")
|
||||
return True
|
||||
|
||||
print(f" Found {len(pending)} pending migration(s)...")
|
||||
|
|
@ -211,12 +211,12 @@ if __name__ == "__main__":
|
|||
if not load_schema():
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("✓ Schema already exists")
|
||||
print("[OK] Schema already exists")
|
||||
|
||||
# Run migrations
|
||||
print("\nRunning database migrations...")
|
||||
if not run_migrations():
|
||||
print("✗ Migration failed")
|
||||
print("[FAIL] Migration failed")
|
||||
sys.exit(1)
|
||||
|
||||
# Check for migration
|
||||
|
|
@ -232,14 +232,14 @@ if __name__ == "__main__":
|
|||
from migrate_to_postgres import main as migrate
|
||||
migrate()
|
||||
except Exception as e:
|
||||
print(f"✗ Migration failed: {e}")
|
||||
print(f"[FAIL] Migration failed: {e}")
|
||||
sys.exit(1)
|
||||
elif os.path.exists(sqlite_db) and profile_count > 0:
|
||||
print(f"⚠ SQLite DB exists but PostgreSQL already has {profile_count} profiles")
|
||||
print(f"[WARN] SQLite DB exists but PostgreSQL already has {profile_count} profiles")
|
||||
print(" Skipping migration (already migrated)")
|
||||
elif not os.path.exists(sqlite_db):
|
||||
print("✓ No SQLite database found (fresh install or already migrated)")
|
||||
print("[OK] No SQLite database found (fresh install or already migrated)")
|
||||
else:
|
||||
print("✓ No migration needed")
|
||||
print("[OK] No migration needed")
|
||||
|
||||
print("\n✓ Database initialization complete")
|
||||
print("\n[OK] Database initialization complete")
|
||||
|
|
|
|||
|
|
@ -21,20 +21,20 @@ from version import APP_VERSION, BUILD_DATE, DB_SCHEMA_VERSION, MODULE_VERSIONS
|
|||
# Run database migrations before API start — halbes Schema ist schlimmer als kein Start
|
||||
# Lokal ohne DB / nur Tests: SKIP_DB_MIGRATE=1
|
||||
if os.getenv("SKIP_DB_MIGRATE", "").strip().lower() in ("1", "true", "yes"):
|
||||
print("⚠ SKIP_DB_MIGRATE=1 — Migrationen wurden übersprungen (nur für Entwicklung ohne DB)")
|
||||
print("[SKIP_DB_MIGRATE] Migrationen uebersprungen (nur fuer Entwicklung ohne DB)")
|
||||
else:
|
||||
try:
|
||||
import run_migrations
|
||||
|
||||
rc = run_migrations.main()
|
||||
if rc != 0:
|
||||
print(f"✗ Datenbank-Migration fehlgeschlagen (Exit-Code {rc}). Start abgebrochen.")
|
||||
print(f"[FAIL] Datenbank-Migration fehlgeschlagen (Exit-Code {rc}). Start abgebrochen.")
|
||||
sys.exit(1)
|
||||
print("✓ Database migrations completed")
|
||||
print("[OK] Database migrations completed")
|
||||
except SystemExit:
|
||||
raise
|
||||
except Exception as e:
|
||||
print(f"✗ Migration-Laufzeitfehler: {e}")
|
||||
print(f"[FAIL] Migration-Laufzeitfehler: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
from routers.auth import limiter as auth_rate_limiter
|
||||
|
|
|
|||
|
|
@ -49,8 +49,9 @@ ON CONFLICT (profile_id, club_id) DO NOTHING;
|
|||
INSERT INTO club_members (profile_id, club_id, status)
|
||||
SELECT DISTINCT elem::int, t.club_id, 'active'
|
||||
FROM training_groups t,
|
||||
LATERAL jsonb_array_elements_text(COALESCE(t.co_trainer_ids, '[]'::jsonb)) AS elem
|
||||
WHERE jsonb_array_length(COALESCE(t.co_trainer_ids, '[]'::jsonb)) > 0
|
||||
LATERAL jsonb_array_elements_text(t.co_trainer_ids) AS elem
|
||||
WHERE jsonb_typeof(t.co_trainer_ids) = 'array'
|
||||
AND jsonb_array_length(t.co_trainer_ids) > 0
|
||||
ON CONFLICT (profile_id, club_id) DO NOTHING;
|
||||
|
||||
INSERT INTO club_member_roles (club_member_id, role_code)
|
||||
|
|
|
|||
|
|
@ -49,14 +49,14 @@ def get_db_connection():
|
|||
password=p["password"],
|
||||
)
|
||||
conn.autocommit = False
|
||||
print(f"✓ Connected to database: {p['dbname']}")
|
||||
print(f"[OK] Connected to database: {p['dbname']}")
|
||||
return conn
|
||||
except psycopg2.OperationalError:
|
||||
if i < max_retries - 1:
|
||||
print(f"Waiting for database... ({i+1}/{max_retries})")
|
||||
time.sleep(2)
|
||||
else:
|
||||
print(f"✗ Failed to connect to database after {max_retries} attempts")
|
||||
print(f"[FAIL] Failed to connect to database after {max_retries} attempts")
|
||||
raise
|
||||
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ def init_migrations_table(conn):
|
|||
"""
|
||||
)
|
||||
conn.commit()
|
||||
print("✓ schema_migrations initialisiert")
|
||||
print("[OK] schema_migrations initialisiert")
|
||||
|
||||
|
||||
_LEADING_DIGITS = re.compile(r"^(\d+)")
|
||||
|
|
@ -190,7 +190,7 @@ def run_migration(conn, migration_name: str, filepath: str) -> bool:
|
|||
if shutil.which("psql"):
|
||||
ok, diag = _run_file_with_psql(filepath)
|
||||
if not ok:
|
||||
print(f" ✗ psql fehlgeschlagen:\n{diag or '(kein Output)'}")
|
||||
print(f" [FAIL] psql fehlgeschlagen:\n{diag or '(kein Output)'}")
|
||||
conn.rollback()
|
||||
return False
|
||||
detail_suffix = "(psql -1)"
|
||||
|
|
@ -199,7 +199,7 @@ def run_migration(conn, migration_name: str, filepath: str) -> bool:
|
|||
with open(filepath, "r", encoding="utf-8") as fh:
|
||||
body = fh.read()
|
||||
except OSError as e:
|
||||
print(f" ✗ kann Datei nicht lesen: {e}")
|
||||
print(f" [FAIL] kann Datei nicht lesen: {e}")
|
||||
conn.rollback()
|
||||
return False
|
||||
|
||||
|
|
@ -207,7 +207,7 @@ def run_migration(conn, migration_name: str, filepath: str) -> bool:
|
|||
with conn.cursor() as cur:
|
||||
if not statements:
|
||||
print(
|
||||
f" ⚠ keine ausführbaren Statements (leer?) — "
|
||||
f" [WARN] keine ausführbaren Statements (leer?) — "
|
||||
f"Eintrag trotzdem: {migration_name}"
|
||||
)
|
||||
else:
|
||||
|
|
@ -217,12 +217,12 @@ def run_migration(conn, migration_name: str, filepath: str) -> bool:
|
|||
|
||||
_record_migration(conn, migration_name)
|
||||
conn.commit()
|
||||
print(f" ✓ {migration_name} erfolgreich {detail_suffix}")
|
||||
print(f" [OK] {migration_name} erfolgreich {detail_suffix}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
print(f" ✗ {migration_name}: {e}")
|
||||
print(f" [FAIL] {migration_name}: {e}")
|
||||
return False
|
||||
|
||||
|
||||
|
|
@ -243,7 +243,7 @@ def main():
|
|||
pending = get_pending(conn, migrations_dir)
|
||||
|
||||
if not pending:
|
||||
print("✓ Keine ausstehenden Migrationen — Schema aktuell.")
|
||||
print("[OK] Keine ausstehenden Migrationen — Schema aktuell.")
|
||||
conn.close()
|
||||
return 0
|
||||
|
||||
|
|
@ -262,17 +262,17 @@ def main():
|
|||
|
||||
print("\n" + "=" * 60)
|
||||
if failed:
|
||||
print(f"✗ Abbruch nach: {failed}")
|
||||
print(f"[FAIL] Abbruch nach: {failed}")
|
||||
print(" (Bereits erfolgreiche Dateien dieser Session sind committed.)")
|
||||
print("=" * 60)
|
||||
return 1
|
||||
|
||||
print(f"✓ {len(pending)} Migration(s) angewendet — Schema aktuell.")
|
||||
print(f"[OK] {len(pending)} Migration(s) angewendet — Schema aktuell.")
|
||||
print("=" * 60)
|
||||
return 0
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n✗ Fehler: {e}")
|
||||
print(f"\n[FAIL] Fehler: {e}")
|
||||
return 1
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Shinkan Jinkendo Version Information
|
||||
|
||||
APP_VERSION = "0.8.12"
|
||||
APP_VERSION = "0.8.14"
|
||||
BUILD_DATE = "2026-05-05"
|
||||
DB_SCHEMA_VERSION = "20260505039"
|
||||
|
||||
|
|
@ -23,6 +23,20 @@ MODULE_VERSIONS = {
|
|||
}
|
||||
|
||||
CHANGELOG = [
|
||||
{
|
||||
"version": "0.8.14",
|
||||
"date": "2026-05-05",
|
||||
"changes": [
|
||||
"DB 039 Fix: Co-Trainer-Backfill nur wenn co_trainer_ids ein JSON-Array ist (vermeidet jsonb_array_length auf Nicht-Array)",
|
||||
],
|
||||
},
|
||||
{
|
||||
"version": "0.8.13",
|
||||
"date": "2026-05-05",
|
||||
"changes": [
|
||||
"Fix: Startup unter Windows (cp1252) — Emoji/Sonderzeichen in print durch ASCII ([OK]/[FAIL]/[WARN]) ersetzt (main, run_migrations, db_init)",
|
||||
],
|
||||
},
|
||||
{
|
||||
"version": "0.8.12",
|
||||
"date": "2026-05-05",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Shinkan Jinkendo Frontend Version
|
||||
|
||||
export const APP_VERSION = "0.8.12"
|
||||
export const APP_VERSION = "0.8.14"
|
||||
export const BUILD_DATE = "2026-05-05"
|
||||
|
||||
export const PAGE_VERSIONS = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user