Orbit / app /db /init_db.py
Orbit Automations
Auto-sync from Julius-606/Orbit monorepo
4a693cf
################################################################################
# FILE: backend/app/db/init_db.py
# VERSION: 1.1.0 | SYSTEM: Neon DB Auto-Migration ๐Ÿš€
################################################################################
import asyncio
from sqlalchemy import text
from app.db.session import async_session, engine
from app.models.study import Base, StudyTask, BrainRotLevel
import logging
logger = logging.getLogger("Orbit-Genesis")
async def ensure_columns_exist():
"""
Ensures that Orbit v4.0.0 columns exist in the database.
This handles migrations manually for environments like HF/Render where
Alembic might not have run or where the DB was created before the schema update.
"""
async with engine.begin() as conn:
logger.info("Checking database schema for Orbit v4.0.0 updates...")
# 1. Check for 'remarks' column
result = await conn.execute(text("""
SELECT column_name
FROM information_schema.columns
WHERE table_name='study_tasks' AND column_name='remarks';
"""))
if not result.fetchone():
logger.info("Adding missing 'remarks' column to 'study_tasks'...")
await conn.execute(text("ALTER TABLE study_tasks ADD COLUMN remarks TEXT;"))
# 2. Check for 'is_reminder' column
result = await conn.execute(text("""
SELECT column_name
FROM information_schema.columns
WHERE table_name='study_tasks' AND column_name='is_reminder';
"""))
if not result.fetchone():
logger.info("Adding missing 'is_reminder' column to 'study_tasks'...")
await conn.execute(text("ALTER TABLE study_tasks ADD COLUMN is_reminder BOOLEAN DEFAULT FALSE;"))
logger.info("Database schema check complete. Orbit is synchronized. ๐Ÿ›ธ")
async def init_models():
"""Creates the tables if they don't exist and ensures columns are correct."""
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
# Run the manual migration fix for existing tables
await ensure_columns_exist()
logger.info("Database tables forged and synchronized successfully. ๐Ÿ”จ")
async def seed_data():
"""Drops some default tasks into the syllabus vault if it's empty."""
async with async_session() as db:
# Check if we already have tasks
result = await db.execute(text("SELECT count(*) FROM study_tasks"))
count = result.scalar()
if count == 0:
task1 = StudyTask(title="Master the Cardiac Cycle", subject="Cardiology", brain_rot_level=BrainRotLevel.COOKED)
task2 = StudyTask(title="Review Prop Firm Drawdown Rules", subject="Forex", brain_rot_level=BrainRotLevel.CHILL)
db.add(task1)
db.add(task2)
await db.commit()
logger.info("Genesis data injected. Orbit is alive.")
else:
logger.info("Data already exists. Skipping seed.")
async def main():
await init_models()
await seed_data()
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
logger.info("Initiating Project Orbit Genesis Protocol...")
asyncio.run(main())