[파이썬] 예제 스크립트로 알아보는 SQLite3 기초 사용법
파이썬에서 sqlite 데이터베이스 사용법에 대해 알아봅니다.
Oracle, MS-SQL, MySql 등의 데이터베이스는 별도의 설치 및 연동과정이 필요합니다.
SQLite3는 별도의 설치 과정 없이 바로 import하여 사용가능하며 데이터베이스 서버의 구성이 필요없습니다.
SQLite3 기본 연동 사용법
1. 데이터베이스를 사용하기 위해 connect()함수를 사용하여 db파일을 생성하고 연결합니다.
isolation_level=None 옵션을 주게되면, update, insert, delete문과 같이 데이터베이스의 데이터에 변화를 주는 쿼리문에 대하여 자동 커밋(commit) 처리를 합니다.
오토커밋을 해제하려면 isolation_level=None 옵션을 제거합니다.
자동 커밋을 해제한 경우 반드시 conn.commit() 또는 conn.rollback()함수를 실행해야합니다.
그렇지 않으면 다른 사용자가 접근할 때 테이블에 락이 걸려 기다리는 상태가 됩니다.
commit()은 데이터베이스에 적용함을 의미하며, rollback()은 작업한 내용을 모두 날린다는 의미입니다.
import sqlite3
#DB 파일 생성 및 연결
conn = sqlite3.connect("C:\python\database\customer_database.db", isolation_level=None)
2. connection에 Cursor객체를 생성 후 execute()함수를 호출하여 SQL 명령을 실행합니다.
# 커서 연결 cursor = conn.cursor()
여기까지 모든 작업을 위한 기본 작업입니다. 위 두 줄의 코드는 항상 쌍으로 구성되어 사용됩니다.
CRUD작업을 할 경우 항상 따라다니게 됩니다.
CRUD는 생성(INSERT), 읽기(SELECT), 갱신(UPDATE), 삭제(DELETE)를 의미합니다. 테이블을 생성하고, 추가하고, 조회하고, 업데이트하고 삭제할때 항상 위 두줄의 코드는 항상 함께합니다.
import sqlite3
#DB 파일 생성 및 연결
conn = sqlite3.connect("C:\python\database\customer_database.db", isolation_level=None)
# 커서 연결
cursor = conn.cursor()
연동작업이 끝났습니다. 이제 테이블 생성을 시도합니다.
모든 쿼리문은 CURSOR의 execute()함수를 사용하여 실행됩니다.
sqlite 테이블 생성(CREATE TABLE)
테이블 생성 구문은 CREATE문를 사용하여 생성합니다.
import sqlite3
#DB 파일 생성 및 연결
conn = sqlite3.connect("C:\python\database\customer_database.db", isolation_level=None)
# 커서 연결
cursor = conn.cursor()
# 테이블 생성
target_tb = "CREATE TABLE IF NOT EXISTS TB_USER_INFO(" \
"userid INTEGER PRIMARY KEY, \
username text, " \
"email text, " \
"phone text, " \
"area text, " \
"regdate text)"
# SQL 실행
cursor.execute(target_tb)
# DB연결 해제
conn.close()
sqlite 데이터 삽입(INSERT)
INSERT INTO 문을 사용하여 테이블에 데이터를 추가할 수 있습니다.
여러개의 데이터를 추가할 경우 executemany()함수를 사용하여 처리하고, 데이터 타입은 튜플이나 리스트 자료형만 가능합니다.
import sqlite3
import datetime
#DB 파일 생성 및 연결
conn = sqlite3.connect("C:\python\database\customer_database.db", isolation_level=None)
# 커서 연결
cursor = conn.cursor()
current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# 데이터 추가
cursor.execute("INSERT INTO TB_USER_INFO
VALUES(1, 'IU', 'iu_test@gmail.com', '010-0000-0000', '서울', ?)", (current_time,))
cursor.execute("INSERT INTO TB_USER_INFO(userid, username, email, phone, area, regdate)
VALUES (?, ?, ?, ?, ?, ?)", (2, 'SUJI', 'suji_test@gmail.com', '010-1234-5678', '광주', current_time))
# 여러개의 데이터를 추가하기(튜플, 리스트)
u_list = (
(3, 'Hong Gildong', 'Gildong@gmail.com', '010-0000-1234', '서울', current_time),
(4, 'Han Jimin', 'Jimin@gmail.com', '010-1234-8765', '서울', current_time)
)
cursor.executemany("INSERT INTO TB_USER_INFO(userid, username, email, phone, area, regdate)
VALUES (?, ?, ?, ?, ?, ?)", u_list)
# DB연결 해제
conn.close()
sqlite 데이터 조회(SELECT)
테이블에 입력한 데이터를 조회하기 위해 SELECT문을 사용합니다.
조회한 결과를 보기 위해서는 fetchone(), fetchall(), fetchmany() 등 3개의 함수를 사용하여 조회결과를 확인할 수 있습니다.
| 메서드 | 내용 |
| fetchone() | 조회 결과에서 1개의 row를 가져옴(Fetches one row from the resultset.) |
| fetchmany(size=2) | 조회 결과에서 지정한 size만큼의 여러 row를 가져옴 (Fetches several rows from the resultset.) |
| fetchall() | 조회 결과에서 모든 행을 가져옴 (Fetches all rows from the resultset.) |
import sqlite3
#DB 파일 생성 및 연결
conn = sqlite3.connect("C:\python\database\customer_database.db", isolation_level=None)
# 커서 연결
cursor = conn.cursor()
#테이블 조회 fetchone, fetchmany, fecthall
cursor.execute("SELECT * FROM TB_USER_INFO ORDER BY userid DESC")
print(cursor.fetchmany(size=1))
print(cursor.fetchone())
print(cursor.fetchone())
print(cursor.fetchall())
# DB연결 해제
conn.close()
다음은 for문을 사용하여 조회 결과 출력하는 예제입니다.
import sqlite3
#DB 파일 생성 및 연결
conn = sqlite3.connect("C:\python\database\customer_database.db", isolation_level=None)
# 커서 연결
cursor = conn.cursor()
#테이블 조회 fetchone, fetchmany, fecthall
cursor.execute("SELECT * FROM TB_USER_INFO ORDER BY userid DESC")
rows = cursor.fetchall()
for item in rows:
print(f'{item}')
# DB연결 해제
conn.close()
다음은 where절을 사용하여 조회하는 예제입니다.
import sqlite3
#DB 파일 생성 및 연결
conn = sqlite3.connect("C:\python\database\customer_database.db", isolation_level=None)
# 커서 연결
cursor = conn.cursor()
#테이블 조회 fetchone, fetchmany, fecthall
cursor.execute("SELECT * FROM TB_USER_INFO ORDER BY userid DESC")
params = (2,)
cursor.execute("SELECT * FROM TB_USER_INFO WHERE userid=?", params)
print(f'{cursor.fetchall()}')
params = (1, 3)
cursor.execute("SELECT * FROM TB_USER_INFO WHERE userid IN (?,?)", params)
print(f'{cursor.fetchall()}')
# DB연결 해제
conn.close()
sqlite 데이터 삭제(DELETE)
DELETE FROM 문을 사용하여 테이블의 데이터를 삭제할 수 있습니다.
SQLite는 테이블 전체 데이터 삭제 기능인 TRUNCATE를 지원하지 않습니다.
DELETE FROM 테이블명과 같은 형식으로 모든 데이터를 삭제합니다.
모든 데이터의 삭제를 방지하려면 WHERE절을 사용하여 처리합니다.
import sqlite3
#DB 파일 생성 및 연결
conn = sqlite3.connect("C:\python\database\customer_database.db", isolation_level=None)
# 커서 연결
cursor = conn.cursor()
# 데이터 삭제
cursor.execute("DELETE FROM TB_USER_INFO WHERE userid = ?", (2,))
# DB연결 해제
conn.close()
다음은 모든 데이터 삭제하는 쿼리 예제 입니다.
cursor.execute("DELETE FROM TB_USER_INFO")
sqlite 데이터 갱신(UPDATE)
UPDATE문을 사용하여 테이블의 데이터를 갱신할 수 있습니다.
import sqlite3
#DB 파일 생성 및 연결
conn = sqlite3.connect("C:\python\database\customer_database.db", isolation_level=None)
# 커서 연결
cursor = conn.cursor()
# 데이터 수정
cursor.execute("UPDATE TB_USER_INFO SET area= ? WHERE userid= ?", ('전주', 2))
# DB연결 해제
conn.close()
SQLite 연동 해제
데이터베이스에서 작업을 완료한 경우 반드시 close()함수를 호출하여 연결을 해제해야합니다.
# DB연결 해제 conn.close()
동일한 기본키(PK)로 추가한 데이터를 또 등록하면 안됩니다. 기본키는 반드시 유니크해야합니다.
import sqlite3
import datetime
#DB 파일 생성 및 연결
conn = sqlite3.connect("C:\python\database\customer_database.db", isolation_level=None)
# 커서 연결
cursor = conn.cursor()
# 테이블에 데이터 삽입
current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
cursor.execute("INSERT INTO TB_USER_INFO "
"VALUES(1, 'IU', 'iu_test@gmail.com', '010-0000-0000', '서울', ?)", (current_time,))
cursor.execute("INSERT INTO TB_USER_INFO "
"VALUES(1, 'IU', 'iu_test@gmail.com', '010-0000-0000', '서울', ?)", (current_time,))
print(cursor.fetchall())
# DB연결 해제
conn.close()
테이블의 키값으로 이미 등록된 키로 또 다른 데이터를 insert를 시도하는 경우 , sqlite3.IntegrityError: UNIQUE constrainty failed: 테이블명.칼럼명 오류가 발생합니다.
테이블 생성시 테이블 칼럼(필드)의 속성으로 PRIMARY KEY 를 지정한 칼럼은 INSERT시 항상 단일키(유니크) 해야하는 것이죠.
사람들의 주민등록번호를 생각하면 이해가 빠를 것으로 생각됩니다.
C:\Users\ilike\AppData\Local\Programs\Python\Python39\python.exe C:/python/Workspace/main.py
Traceback (most recent call last):
File "C:\python\Workspace\main.py", line 13, in <module>
cursor.execute("INSERT INTO TB_USER_INFO "
sqlite3.IntegrityError: UNIQUE constraint failed: TB_USER_INFO.userid
데이터베이스 락이 걸렸을 때 sqlite3.OperationalError: database is locked 오류가 발생됩니다.
이는 다른 프로그램이나 또 다른 창에서 이미 데이터베이스에 접근하여 insert문이나 update문 혹은 delete문을 실행함으로 써 다른 사용자의 데이터베이스 작업을 못하도록 막는 장치 중에 하나입니다.
먼저 선점한 사용자의 작업이 완료되어야 접근할 수 있습니다.
conn.commit()를 치거나 conn.rollback()를 실행하여야 락이 해제됩니다.
Traceback (most recent call last):
File "C:\python\Workspace\main.py", line 23, in <module>
cursor.execute("DELETE FROM TB_USER_INFO")
sqlite3.OperationalError: database is locked
테이블이 이미 존재하는 경우에 동일한 테이블을 생성하는 경우 sqlite3.OperationalError: table TB_USER_INFO already exists 오류를 만나게 됩니다. 그럼으로 테이블 생성시 IF NOT EXISTS 조건을 두어 생성해야 합니다.
# 테이블 생성
target_tb = "CREATE TABLE IF NOT EXISTS TB_USER_INFO(" \
"userid INTEGER PRIMARY KEY, \
username text, " \
"email text, " \
"phone text, " \
"area text, " \
"regdate text)"
sqlite 테이블 삭제하기
테이블을 삭제할 때는 DROP TABLE 문을 사용합니다.
import sqlite3
import datetime
#DB 파일 생성 및 연결
conn = sqlite3.connect("C:\python\database\customer_database.db", isolation_level=None)
# 커서 연결
cursor = conn.cursor()
# 테이블 삭제
conn.execute("DROP TABLE TB_USER_INFO")
# DB연결 해제
conn.close()
sqlite 데이터베이스(DB) 데이터 백업하는 방법
1. db파일을 항상 백업합니다.
원본 파일 : customer_database.db 백업 파일 : customer_database_backup.2020.26.db
2. DB 데이터를 덤프(dump) 떠서 스크립트로 보관할 수 있습니다. 아래 스크립트를 실행하면 스크립트를 얻을 수 있어요.
import sqlite3
# DB 파일 생성 및 연결
conn = sqlite3.connect("C:\python\database\customer_database.db", isolation_level=None)
# 커서 연결
cursor = conn.cursor()
with conn:
with open("C:\python\database\dump_script.sql", 'w') as f:
for line in conn.iterdump():
f.write('%s\n' % line)
conn.close()
dump_script.sql 파일을 메모장으로 열어보면 위에서 작업했던 테이블 생성문과 insert문으로 추가했던 스크립트가 그대로 생성됩니다.
나중에 DB이관 작업을 할 때 유용하게 사용될 수 있습니다.
BEGIN TRANSACTION;
CREATE TABLE "TB_LOGIN_HIST" (
"SEQ" INTEGER NOT NULL,
"LOGIN_ID" TEXT NOT NULL,
"LOGIN_DATE" TEXT NOT NULL,
PRIMARY KEY("SEQ" AUTOINCREMENT)
);
CREATE TABLE TB_USER_INFO(userid INTEGER PRIMARY KEY, username text, email text, phone text, area text, regdate text);
INSERT INTO "TB_USER_INFO" VALUES(1,'IU','iu_test@gmail.com','010-0000-0000','서울','2020-12-26 18:41:36');
INSERT INTO "TB_USER_INFO" VALUES(2,'SUJI','suji_test@gmail.com','010-1234-5678','전주','2020-12-26 18:41:36');
INSERT INTO "TB_USER_INFO" VALUES(3,'Hong Gildong','Gildong@gmail.com','010-0000-1234','서울','2020-12-26 18:41:36');
INSERT INTO "TB_USER_INFO" VALUES(4,'Han Jimin','Jimin@gmail.com','010-1234-8765','서울','2020-12-26 18:41:36');
DELETE FROM "sqlite_sequence";
COMMIT;
sqlite3 데이터베이스 조회 결과를 pandas DataFrame 타입으로 가져오는 방법
pandas.read_sql_query()함수를 사용하여 조회결과 전체를 DataFrame타입으로 변환할 수 있습니다.
import sqlite3
import pandas as pd
conn = sqlite3.connect("C:\python\database\customer_database.db", isolation_level=None)
df = pd.read_sql_query("SELECT * FROM TB_USER_INFO", conn)
print(df)
#실행결과
userid username ... area regdate
0 1 IU ... 서울 2020-12-26 18:41:36
1 2 SUJI ... 전주 2020-12-26 18:41:36
2 3 Hong Gildong ... 서울 2020-12-26 18:41:36
3 4 Han Jimin ... 서울 2020-12-26 18:41:36
[4 rows x 6 columns]
활용 팁
print문을 사용하여 데이터에 대한 처리 결과를 보기가 불편할 때는 SQLite 툴을 설치하세요. 굉장히 유용합니다.
[REFERENCE]
docs.python.org/ko/3/library/sqlite3.html
stackoverflow.com/questions/36028759/how-to-open-and-convert-sqlite-database-to-pandas-dataframe
[더 보기]
https://github.com/ghaering/pysqlite
pysqlite 웹 페이지 – sqlite3은 《pysqlite》라는 이름으로 외부에서 개발되었습니다.
pythonexamples.org/python-sqlite3-tutorial/
SQLite 웹 페이지; 설명서는 지원되는 SQL 언어에 대한 문법과 사용 가능한 데이터형을 설명합니다.
https://www.w3schools.com/sql/
SQL 문법 학습을 위한 자습서, 레퍼런스 및 예제
