Statement 한 개로 insert-or-update
3.24 이전엔 INSERT OR REPLACE (delete + reinsert, FK 깨짐) 또는 직접 select-then-insert-or-update 작성. 모던 SQLite 가 진짜 UPSERT 제공:
INSERT INTO t(...) VALUES (...)
ON CONFLICT(unique_col) DO UPDATE SET other_col = excluded.other_col;가짜 테이블 excluded 가 insert 됐을 row 참조. 어떤 컬럼 subset 도 SET 가능, 어떤 표현식도 사용 가능.
RETURNING (3.35+) 가 같은 round-trip 에서 영향 받은 row 데이터 반환:
INSERT INTO t(...) VALUES (...) RETURNING id, created_at;합치면 INSERT...ON CONFLICT...DO UPDATE...RETURNING 가 'create or update + 결과 알려줘' 를 한 statement 에 — REST API write path 의 기본기.
Self-reference: 피파의
add_message 가 INSERT...RETURNING 으로 두 번째 SELECT 없이 새 message id 받아옴. conn.row_factory = sqlite3.Row 와 합치면 갓 insert 된 row 를 한 round-trip 으로 API 에 반환.