mirror of
https://github.com/KohakuBlueleaf/KohakuHub.git
synced 2026-04-28 09:57:43 -05:00
Database Migrations
This directory contains database migration scripts for KohakuHub.
How Migrations Work
- Auto-detection: Each migration checks if it needs to run by verifying if columns/tables exist
- Sequential execution: Migrations run in numerical order (001, 002, 003, etc.)
- Idempotent: Safe to run multiple times - already-applied migrations are skipped
- Auto-run: Migrations automatically run on container startup via
docker/startup.py
Migration Order
| # | Name | Description |
|---|---|---|
| 001 | repository_schema | Remove unique constraint from Repository.full_id |
| 002 | user_org_quotas | Add private/public quota fields to User/Organization |
| 003 | commit_tracking | Add Commit table for tracking user commits |
| 004 | repo_quotas | Add quota/used_bytes fields to Repository |
Creating New Migrations
-
Create a new file:
scripts/db_migrations/00X_name.py -
Implement these functions:
check_migration_needed()- Returns True if migration should runmigrate_sqlite()- SQLite migration logicmigrate_postgres()- PostgreSQL migration logicrun()- Main entry point
-
Template:
#!/usr/bin/env python3
"""Migration 00X: Description"""
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "src"))
from kohakuhub.db import db
from kohakuhub.config import cfg
def check_migration_needed():
"""Check if columns/tables exist."""
cursor = db.cursor()
if cfg.app.db_backend == "postgres":
cursor.execute("""
SELECT column_name FROM information_schema.columns
WHERE table_name='mytable' AND column_name='mycolumn'
""")
return cursor.fetchone() is None
else:
cursor.execute("PRAGMA table_info(mytable)")
columns = [row[1] for row in cursor.fetchall()]
return 'mycolumn' not in columns
def migrate_sqlite():
cursor = db.cursor()
cursor.execute("ALTER TABLE mytable ADD COLUMN mycolumn INTEGER")
db.commit()
def migrate_postgres():
cursor = db.cursor()
cursor.execute("ALTER TABLE mytable ADD COLUMN mycolumn BIGINT")
db.commit()
def run():
db.connect(reuse_if_open=True)
try:
if not check_migration_needed():
print("Migration 00X: Already applied")
return True
print("Migration 00X: Running...")
if cfg.app.db_backend == "postgres":
migrate_postgres()
else:
migrate_sqlite()
print("Migration 00X: ✓ Completed")
return True
except Exception as e:
print(f"Migration 00X: ✗ Failed - {e}")
return False
finally:
db.close()
if __name__ == "__main__":
success = run()
sys.exit(0 if success else 1)
Running Migrations
Automatic (in Docker):
- Migrations run automatically on container startup
Manual:
# Run all migrations
python scripts/run_migrations.py
# Run specific migration
python scripts/db_migrations/001_repository_schema.py
Notes
- Migrations are idempotent - safe to re-run
- Failed migrations will prevent server startup
- Old migration scripts in
scripts/migrate_*.pyare kept for reference