Research.io / core /database.py
Prince-2025's picture
Initial Upload for Deployment.
ad94b49 verified
Raw History Blame Contribute Delete
2.64 kB
"""
asyncpg-based connection pool for PostgreSQL (Neon DB).
No SQLAlchemy. Raw SQL with $1/$2 style parameters.
"""
import asyncpg
import logging
from core.config import settings
logger = logging.getLogger(__name__)
_pool: asyncpg.Pool | None = None
def _dsn() -> str:
"""asyncpg requires postgresql:// not postgresql+asyncpg://"""
url = settings.DATABASE_URL
return url.replace("postgresql+asyncpg://", "postgresql://").replace("postgres+asyncpg://", "postgresql://")
async def init_pool():
global _pool
_pool = await asyncpg.create_pool(
dsn=_dsn(),
min_size=2,
max_size=10,
command_timeout=30,
)
async def close_pool():
global _pool
if _pool:
await _pool.close()
_pool = None
def get_pool() -> asyncpg.Pool:
if _pool is None:
raise RuntimeError("DB pool not initialised — call init_pool() first.")
return _pool
async def init_db():
"""Create tables with consistent TEXT types for IDs."""
logger.info("Initializing database tables...")
async with get_pool().acquire() as conn:
await conn.execute("""
CREATE TABLE IF NOT EXISTS papers (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
source_url TEXT DEFAULT 'local',
storage_url TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS conversations (
id TEXT PRIMARY KEY,
mode TEXT NOT NULL,
paper_a_id TEXT REFERENCES papers(id) ON DELETE CASCADE,
paper_b_id TEXT REFERENCES papers(id) ON DELETE CASCADE,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS messages (
id TEXT PRIMARY KEY,
conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
user_msg TEXT NOT NULL,
assistant_msg TEXT NOT NULL,
sources JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS debate_sessions (
id TEXT PRIMARY KEY,
conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE UNIQUE,
perspective TEXT,
debate_data JSONB,
winner TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
""")
logger.info("Database tables verified.")