mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-06-17 23:09:35 +00:00
- Wrap PostHog/DLQ init in try/except so startup survives missing services - Delay self-improvement worker 30s to reduce startup load - Run init_db() for ALL database types (was SQLite-only, skipping PostgreSQL) - Add 3-attempt retry with backoff in init_db() for Railway DB startup race - Fix FastAPI deprecation: regex → pattern in intelligence.py - Remove hardcoded Ultramsg credentials from auto_pipeline.py https://claude.ai/code/session_01W1rJthWDkasijTdXCfxVHs
94 lines
2.8 KiB
Python
94 lines
2.8 KiB
Python
import os
|
|
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker
|
|
from sqlalchemy.orm import DeclarativeBase
|
|
from sqlalchemy import text
|
|
|
|
|
|
def _get_db_url() -> str:
|
|
url = os.environ.get("DATABASE_URL", "")
|
|
if not url:
|
|
for env_file in [".env", "../.env"]:
|
|
try:
|
|
with open(env_file) as f:
|
|
for line in f:
|
|
if line.strip().startswith("DATABASE_URL="):
|
|
url = line.strip().split("=", 1)[1]
|
|
break
|
|
except FileNotFoundError:
|
|
continue
|
|
if not url:
|
|
return "sqlite+aiosqlite:///./dealix.db"
|
|
# Railway Postgres gives postgres:// but SQLAlchemy needs postgresql+asyncpg://
|
|
if url.startswith("postgres://"):
|
|
url = url.replace("postgres://", "postgresql+asyncpg://", 1)
|
|
elif url.startswith("postgresql://"):
|
|
url = url.replace("postgresql://", "postgresql+asyncpg://", 1)
|
|
return url
|
|
|
|
|
|
_DB_URL = _get_db_url()
|
|
IS_SQLITE = "sqlite" in _DB_URL.lower()
|
|
|
|
if IS_SQLITE:
|
|
engine = create_async_engine(
|
|
_DB_URL,
|
|
echo=False,
|
|
connect_args={"check_same_thread": False},
|
|
)
|
|
else:
|
|
engine = create_async_engine(
|
|
_DB_URL,
|
|
echo=False,
|
|
pool_size=20,
|
|
max_overflow=10,
|
|
pool_pre_ping=True,
|
|
)
|
|
|
|
async_session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
|
|
|
# Aliases for backward compatibility with workers
|
|
SessionLocal = async_session
|
|
async_session_factory = async_session
|
|
|
|
|
|
class Base(DeclarativeBase):
|
|
pass
|
|
|
|
|
|
async def get_db():
|
|
async with async_session() as session:
|
|
try:
|
|
yield session
|
|
await session.commit()
|
|
except Exception:
|
|
await session.rollback()
|
|
raise
|
|
finally:
|
|
await session.close()
|
|
|
|
|
|
async def init_db():
|
|
import app.models # noqa: F401 — register all models on Base.metadata before create_all
|
|
|
|
for attempt in range(3):
|
|
try:
|
|
async with engine.begin() as conn:
|
|
if not IS_SQLITE:
|
|
for ext in ["CREATE EXTENSION IF NOT EXISTS vector",
|
|
"CREATE EXTENSION IF NOT EXISTS pg_trgm"]:
|
|
try:
|
|
await conn.execute(text(ext))
|
|
except Exception:
|
|
pass
|
|
await conn.run_sync(Base.metadata.create_all)
|
|
print("✅ Database initialized")
|
|
return
|
|
except Exception as e:
|
|
if attempt < 2:
|
|
import asyncio
|
|
print(f"⚠️ DB init attempt {attempt + 1} failed: {e}, retrying in 3s...")
|
|
await asyncio.sleep(3)
|
|
else:
|
|
print(f"❌ DB init failed after 3 attempts: {e}")
|
|
raise
|