이 글에서는 Python의 sqlite3 모듈을 사용하여 클래스 객체 데이터를 SQLite 데이터베이스의 테이블에 저장하고, 다시 조회하는 방법을 단계별로 살펴봅니다.
전체 처리 흐름
기본적인 작업 순서는 다음과 같습니다.
- sqlite3 모듈을 임포트하고 데이터베이스 파일에 연결합니다.
- CREATE TABLE 문으로 테이블 구조를 생성합니다.
- 명명된 매개변수(named parameter) 방식으로 객체 데이터를 INSERT 합니다.
- SELECT 문으로 조건에 맞는 데이터를 조회합니다.
- 변경 사항을 commit한 뒤 연결을 종료합니다.
예제 코드
# sqlitedemo.py
import sqlite3
from employee import Employee
conn = sqlite3.connect('employee.db')
c = conn.cursor()
c.execute('''CREATE TABLE employee(first text, last text, pay integer)''')
emp_1 = Employee('John', 'Doe', 50000)
emp_2 = Employee('Jane', 'Doe', 60000)
emp_3 = Employee('James', 'Dell', 80000)
c.execute('''INSERT INTO employee VALUES(:first, :last, :pay)''',
{'first': emp_1.first, 'last': emp_1.last, 'pay': emp_1.pay})
c.execute('''INSERT INTO employee VALUES(:first, :last, :pay)''',
{'first': emp_2.first, 'last': emp_2.last, 'pay': emp_2.pay})
c.execute('''INSERT INTO employee VALUES(:first, :last, :pay)''',
{'first': emp_3.first, 'last': emp_3.last, 'pay': emp_3.pay})
c.execute("SELECT * FROM employee WHERE last='Doe'")
print(c.fetchone())
print(c.fetchmany(2))
conn.commit()
conn.close()
실행 결과
(u'John', u'Doe', 50000) [(u'John', u'Doe', 50000), (u'Jane', u'Doe', 60000)]
코드 핵심 포인트
1. 명명된 매개변수(Named Parameters) 사용
:first, :last, :pay처럼 콜론 기반의 자리표시자를 사용하면 값이 딕셔너리 형태로 바인딩됩니다. 이는 문자열 포맷팅으로 SQL을 직접 조립하는 것보다 안전하며, SQL 인젝션 공격을 효과적으로 방지할 수 있습니다.
2. 데이터 조회 메서드
fetchone()– 결과 집합에서 한 행만 반환합니다.fetchmany(n)– 지정한 개수(n)만큼 행을 리스트로 반환합니다.fetchall()– 남은 모든 행을 한 번에 반환합니다.
3. commit()과 close()의 중요성
INSERT 작업은 commit()을 호출하기 전까지 실제 데이터베이스 파일에 반영되지 않습니다. 따라서 프로그램 종료 전 반드시 commit을 실행하고, 리소스 누수를 막기 위해 close()로 연결을 닫아야 합니다.
이 패턴을 응용하면 실무에서도 Python 객체를 관계형 데이터베이스에 손쉽게 영속화(persist)할 수 있습니다.