본문 바로가기
C.W.K.
Stream
Lesson 02 of 10 · published

Cursor — execute, fetchone, fetchall

~12 min · python, cursor, fetch

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

SQL이 실제로 도는 자리

SQL statement는 전부 cursor를 거쳐서 돌아. conn.execute(sql, params)를 부르면 cursor가 하나 나와. 부를 때마다 새로 만들어져. row를 읽는 방법은 넷이야.

  • cursor.fetchone() — 다음 row를 tuple로 주고, 없으면 None을 줘.
  • cursor.fetchmany(n) — 최대 n개까지 tuple 목록으로 줘.
  • cursor.fetchall() — 남은 걸 전부 줘. 양이 어마어마할 수 있으니 조심해.
  • Iterationfor row in cursor:는 필요할 때마다 하나씩 흘려줘. 결과가 클 때는 이게 정석이야.
Tip: 기본은 iteration으로 잡아. 백만 row짜리 query에 fetchall()을 쓰면 tuple 백만 개를 한꺼번에 메모리에 올려. iterator는 한 번에 하나씩만 들고 있어.

Code

읽는 방법 3 가지·python
import sqlite3

conn = sqlite3.connect('demo.db')

# fetchone — 단일 row
row = conn.execute('SELECT * FROM users WHERE id = ?', (1,)).fetchone()
print(row)  # tuple 또는 None

# fetchmany — 제한 batch
batch = conn.execute('SELECT * FROM users LIMIT 100').fetchmany(20)
print(len(batch), 'rows')

# Iterate — streaming, 큰 결과의 idiomatic
for user_id, email in conn.execute('SELECT id, email FROM users'):
    print(user_id, email)
Cursor metadata·python
cur = conn.execute('SELECT id, email, username FROM users LIMIT 1')
print(cur.description)
# (('id', None, ...), ('email', None, ...), ('username', None, ...))

print([d[0] for d in cur.description])
# ['id', 'email', 'username']

# Execute 후 INSERT 면 lastrowid 설정
cur = conn.execute('INSERT INTO users(email) VALUES (?)', ('z@x.com',))
print(cur.lastrowid)
# 42

External links

Exercise

query 결과를 한 번에 하나씩 내보내는 generator 함수를 써봐. cursor iteration을 쓰면 돼. row가 10만 개인 테이블을 처리하면서 최대 메모리가 낮게 유지되는지 확인해. tracemalloc이나 OS의 프로세스 모니터로 보면 돼. 그다음 fetchall()로 다시 돌려서 차이를 눈으로 봐.

Progress

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

댓글 0

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

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