C.W.K.
Stream
Lesson 03 of 06 · published

SQLite + aiosqlite — 한 사람을 위한 정답 DB

~14 min · sqlite, schema, migration

Level 0호기심
0 XP0/65 lessons0/17 achievements
0/100 XP to next level100 XP to go0% complete

cwkPippa 가 SQLite 쓰는 이유

한 user. 한 Mac. 수만 개 메시지, 천천히 자람. Postgres 는 overkill. 전체 DB 가 / 의 단일 파일, Time Machine 이 다른 파일처럼 백업. 0 admin.

aiosqlite 가 SQLite 를 async API 로 감쌈. 같은 SQL, async/await 친화. FastAPI 에 자연스럽게 fit.

스키마는 plain SQL, ORM 없음

cwkPippa 는 SQLAlchemy 안 써. 스키마는 backend/store/conversations.py 의 몇 개 CREATE TABLE. 마이그레이션은 init_db 라는 idempotent 함수의 ALTER TABLE — 컬럼 추가? PRAGMA table_info 로 먼저 체크, missing 일 때만 추가.

mirror 원칙

SQLite 는 JSONL ground truth 의 convenience mirror. drift 시 (corruption, schema 변경 잘못, partial write) 복구는 *그 conversation 의 row 비우고 JSONL replay*. SQLite 직접 패치 절대 X. Truth track 에서 어렵게 배움.

parameterized query 항상: 이 머신엔 나만 있어도, 모든 query 가 ? placeholder 거쳐. SQL injection 만이 이유 아냐 — 적절한 SQLite type coercion 받는 방법이기도. SQLite 에서 string 과 bytes 가 기대대로 자동 변환 안 됨.

Code

Schema init — ORM 없는 idempotent 마이그레이션·python
import aiosqlite

async def init_db(db_path: str):
    async with aiosqlite.connect(db_path) as db:
        await db.execute("""
            CREATE TABLE IF NOT EXISTS conversations (
                id TEXT PRIMARY KEY,
                title TEXT,
                created_at TEXT NOT NULL,
                claude_session_id TEXT
            )
        """)
        await db.execute("""
            CREATE TABLE IF NOT EXISTS messages (
                id TEXT PRIMARY KEY,
                conversation_id TEXT NOT NULL,
                role TEXT NOT NULL,
                content TEXT,
                parent_id TEXT,
                brain TEXT DEFAULT 'claude',
                reasoning_level TEXT,
                thinking TEXT,
                created_at TEXT NOT NULL,
                FOREIGN KEY (conversation_id) REFERENCES conversations(id)
            )
        """)
        # Idempotent column add — safe to run repeatedly
        cols = {r[1] for r in await (await db.execute('PRAGMA table_info(messages)')).fetchall()}
        if 'thinking' not in cols:
            await db.execute('ALTER TABLE messages ADD COLUMN thinking TEXT')
        await db.commit()

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 똘이warm💛 by 피파warm

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.