C.W.K.
Stream
Lesson 07 of 10 · published

Custom SQL 함수 + 집계

~12 min · python, create_function, extensibility

Level 0Scout
0 XP0/80 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

SQL 안에서 Python 호출

SQLite 가 SQL 에서 호출 가능한 Python 함수 등록 허용. 엔진 안의 진짜 first-class 함수 — WHERE, SELECT list, 인덱스, trigger 에서 사용 가능. 주요 API 둘:

  • conn.create_function(name, n_args, callable, deterministic=False) — scalar 함수 (한 row in, 한 row out).
  • conn.create_aggregate(name, n_args, AggregateClass) — 집계 (여러 row in, 한 값 out).

Use case: regex 매칭 (regex extension 없을 때), 도메인-specific 스코어링 함수, JSON1 보다 Python 이 더 잘하는 JSON 조작, custom 비교 함수.

Warning: Python-side 함수가 호출마다 C/Python 경계 cross. SQL 기준 느림. 정확성 > 처리량일 때 — 백만 row hot loop 에서 X.

Code

Scalar 함수 — SQL 에서 Python regex·python
import sqlite3, re

def regexp(pattern, value):
    if value is None:
        return False
    return re.search(pattern, value) is not None

conn = sqlite3.connect('demo.db')
conn.create_function('regexp', 2, regexp, deterministic=True)

rows = conn.execute(
    "SELECT * FROM users WHERE email REGEXP '^a.*@gmail\\.com$'"
).fetchall()
집계 — window 의 running average·python
class StdDev:
    def __init__(self):
        self.values = []

    def step(self, value):
        if value is not None:
            self.values.append(value)

    def finalize(self):
        if not self.values:
            return None
        m = sum(self.values) / len(self.values)
        v = sum((x - m) ** 2 for x in self.values) / len(self.values)
        return v ** 0.5

conn.create_aggregate('stddev', 1, StdDev)
row = conn.execute('SELECT stddev(score) FROM submissions').fetchone()
print(row[0])

External links

Exercise

Python regexp 함수 등록 + WHERE 절에서 복잡 패턴 매치. 그 다음 median 계산하는 Python 집계 (SQLite 빌트인 median 없음). 큰 테이블에서 Python 집계 vs SELECT ... ORDER BY ... LIMIT 1 OFFSET n/2 wall-clock 비교.

Progress

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

댓글 0

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

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