"""init_db() baseline 부팅 런타임 검증 (R1) — psql migration_smoke 가 못 잡는 asyncpg 경로 확인. migration_smoke.sh(psql)는 SQL 유효성만 검증한다. init_db 는 asyncpg exec_driver_sql(prepared) 경로라 ① multi-statement 불허 ② baseline 의 raw asyncpg 적재 ③ skip/stamp/멱등 — 이걸 실측한다. 실행 (worktree 루트): python3.11 -m venv /tmp/v && /tmp/v/bin/pip install -q "sqlalchemy[asyncio]>=2" asyncpg pydantic pyyaml docker run -d --name idb -p 55432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust pgvector/pgvector:pg16 docker exec idb psql -U postgres -c "CREATE DATABASE pkm" ln -sfn ../migrations app/migrations # Docker 의 /app/migrations 레이아웃 모사 (테스트 후 rm) PYTHONPATH=app DATABASE_URL="postgresql+asyncpg://postgres@localhost:55432/pkm" /tmp/v/bin/python scripts/ci/initdb_runtime_test.py rm -f app/migrations; docker rm -f idb 기대: 1st OK(documents=True·purge_col=1·cand_qwen=0·attempt_unique=1), 2nd 멱등동일=True. """ import asyncio from sqlalchemy import text async def main(): from core.config import settings url = settings.database_url print("effective DATABASE_URL:", url) assert "localhost" in url or "127.0.0.1" in url, f"SAFETY ABORT non-local: {url}" from core.database import init_db, async_session, engine print("=== 1st init_db (fresh DB) ===") await init_db() async with async_session() as s: cnt = (await s.execute(text("SELECT count(*) FROM schema_migrations"))).scalar() mx = (await s.execute(text("SELECT max(version) FROM schema_migrations"))).scalar() bl = (await s.execute(text("SELECT count(*) FROM schema_migrations WHERE name LIKE 'baseline:%'"))).scalar() docs = (await s.execute(text("SELECT to_regclass('public.documents') IS NOT NULL"))).scalar() purge = (await s.execute(text("SELECT count(*) FROM information_schema.columns WHERE table_name='documents' AND column_name='purge_requested_at'"))).scalar() cand = (await s.execute(text("SELECT count(*) FROM information_schema.tables WHERE table_name LIKE 'documents_cand_qwen%'"))).scalar() uq = (await s.execute(text("SELECT count(*) FROM pg_indexes WHERE indexname='uq_attempt_session_question'"))).scalar() print(f" schema_migrations count={cnt} max={mx} baseline_stamped={bl}") print(f" documents={docs} purge_col={purge} cand_qwen_tables={cand} attempt_unique={uq}") assert docs and purge == 1 and cand == 0 and uq == 1, "FAIL: 기대 스키마 상태 불일치" print("=== 2nd init_db (rerun = baseline skip + 멱등) ===") await init_db() async with async_session() as s: cnt2 = (await s.execute(text("SELECT count(*) FROM schema_migrations"))).scalar() assert cnt == cnt2, "FAIL: 멱등 아님 (재실행이 schema_migrations 변경)" print(f" count={cnt2} 멱등동일={cnt == cnt2}") print("RESULT: PASS — init_db baseline 부팅/멱등 검증") await engine.dispose() asyncio.run(main())