티스토리 뷰

728x90

파일로 처리했을 때 데이터가 많아지면 데이터들을 관리하기가 힘들어집니다. 우리는 그렇게 사용 해봤습니다.

이 전 글 참조

이런저런 조건으로 검색을 했을 때에 대한 소스들도 일일이 다 작성을 해야 겠죠. 이런 문제를 해결하기 위해 DB(DataBase)를 사용합니다. 

데이터 베이스에 대한 자세한 설명은 위키백과 사전 링크로 대신합니다.

데이터 베이스

 

데이터베이스 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. SQL 데이터베이스 쿼리의 예. 데이터베이스(영어: database, DB)는 여러 사람이 공유하여 사용할 목적으로 체계화해 통합, 관리하는 데이터의 집합이다.[1] 작성된 ��

ko.wikipedia.org

여러 데이터 베이스 시스템 중에서 일반적으로 많이 쓰이는 mysql이나 mariadb 같은 DB를 사용을 합니다. 

우리는 저런 DB 서버 시스템을 사용 하기 전에 간단하게 로컬에서 사용할 수 있는 데이터베이스로 사용법을 익히기 위해 sqlite를 사용할 것입니다. 그다음에는  우리 로컬 PC에 mysql이나  mariadb를 설치해도 되고 클라우드에 있는 DB를 이용할 수 있습니다. 또는  pythonanywere 사이트에서 제공해주는 DB를 사용할 수 있습니다. pythonanywere 사이트는 우리 플라스크 웹 애플리케이션을 서비스 가능 하게 호스팅도 가능합니다.

 

 

sqlite는 따로 설치 과정 필요 없이 python 기본 패키지에 포함이 되어 있어 바로 사용 가능합니다.

import sqlite3

 

여기서는 간단하게 사용하는 방법을 사용합니다. 전체 프로세스를 보면

# 1. sqlite를 import 시킵니다.
import sqlite3

# 2. DB에 연결
conn = sqlite3.connect('db파일')

# 3. 쿼리 작성
query = "SQL 쿼리"

# 4. 쿼리 실행
result = conn.execute(query)

다른 DB와 사용법이 비슷하기 때문에(심지어 안에 쿼리문 까지도) DB를 배웠으면 바로 사용이 가능합니다.

그리고 sqlite 만 할 줄 알아도 다른 DB로 바꾸는 과정은 쉽습니다.

DB 쿼리는 우리가 다루는 범위가 아니기 때문에 간단하게 꼭 알아야 할 쿼리 몇 가지만 알고 쿼리를 알고 있다는 가정하에 진행하도록 합니다.

이전에 우리는 학번과 이름을 입력을 받는 폼을 만들고 데이터를 GET이나 POST로 받아 오는 소스를 작성했습니다. (이전 글을 참조)

학번과 이름을 저장하는 테이블을 만들어야 합니다. 테이블 생성 쿼리는 아래와 같습니다.

CREATE TABLE student (num varchar(50), name varchar(50))

num과 name으로 컬럼명을 만들고 타입은 varchar(50) 로 정의를 하면 50byte 크기의 가변 길이의 문자열을 저장시킬 수 있는 컬럼을 가진 student 테이블이 생성이 됩니다.

이제 이 테이블에 데이터를 넣어야 합니다. 데이터를 넣는 쿼리는 아래와 같습니다.

INSERT INTO student VALUES ('20201234', '파이썬')

입력된 데이터를 확인하는 쿼리는 다음과 같습니다. student 테이블의 전체를 보는 쿼리입니다.

SELECT * FROM student

이제 학번으로 한 학생의 데이터를 가져오는 쿼리를 해봅시다.

SELECT * FROM student WHERE num = '20201234'

이제 우리는 기본적인 데이터를 저장하고 불러오기가 가능합니다. 실제 우리가 웹에서 사용되는 방식도 브라우저에서 사용자가 데이터를 입력하면 서버로 전송이 되고 서버로 전송된 데이터는 DB에서 저장을 하고 사용자가 요청하는 정보를 다시 DB에서 꺼내어 보여주는 패턴이기 때문에 이 정도만 알아도 충분합니다.

 

파이썬에서 sqlite를 이용해서 위 쿼리들을 어떻게 사용하는지 알아보죠.

파이썬 파일을 하나 생성합니다. 저는 dbtest.py 라는 이름으로 만들었습니다.

먼저 sqlite  모듈을 소스에 포함을 시킵니다. 그리고 db 파일을 생성을 하고 그  db 파일을 연결해서 테이블을 만들어 봅시다. 소스는 아래와 같습니다.

* 참고: 쿼리의 경우 보통 길게 쓰이게 되는 경우 다음 줄로 넘어가는 경우가 많습니다. 이때 파이썬에서 문자열 쓸 때 따옴표 3개( ''' )를 사용하면 이스케이프 문자(\n 다음 줄) 들을 사용 하지 않아도 문자열을 깔끔하게 쓸 수 있습니다.

import sqlite3
conn = sqlite3.connect('mydb.db')

# Cursor 객체 생성
c = conn.cursor()

# 테이블 생성
c.execute("CREATE TABLE student (num varchar(50), name varchar(50))")
    
# execute 에 db 에 적용
conn.commit()

# 접속한 db 닫기
conn.close()

위 소스에서 mydb.db 파일이 생성이 되고 mydb.db 파일에 연결 후 cursor 객체 생성 부분에서 cursor 객체 생성해야 execute('쿼리') 함수를 사용할 수 있게 됩니다. execute() 함수는 쿼리를 실행시켜주는 함수입니다. 그리고 데이터 삽입 또는 수정을 할 경우 commit을 해야 최종적으로 db에 데이터가 저장이 됩니다. 그리고 접속한 db를 close로 닫습니다.

 

이제 데이터를 insert into 쿼리로 넣어 봅시다.

import sqlite3
conn = sqlite3.connect('mydb.db')

# Cursor 객체 생성
c = conn.cursor()

# 데이터 삽입
c.execute("INSERT INTO student VALUES ('20201234', '파이썬')")
    
# execute 에 db 에 적용
conn.commit()

# 접속한 db 닫기
conn.close()

들어간 데이터를 select 쿼리로 확인해봅니다.

import sqlite3
conn = sqlite3.connect('mydb.db')

# Cursor 객체 생성
c = conn.cursor()

# 데이터 불러 와서 출력
for row in c.execute('SELECT * FROM student'):
    print(row)

# 접속한 db 닫기
conn.close()

exectute 함수를 for 루프 문으로 불어오는 이유는 쿼리가 student 테이블에 전체 데이터를 가져오게 되고 가져온 데이터만큼 반복해서 출력을 하게 됩니다. for 문으로 출력을 했는데 만약 여기서 화면에 출력하는 것을 처리하지 않고 row 결과 데이터들을 받아 전달하는 함수를 만든 다면 전체 데이터를 불러오는 함수를 사용해서 전달할 수 있습니다. 아래 fetchall()이라는 함수가 되겠습니다. 아래 하나의 데이터를 가져오는 함수는  fetchone()인데 all(전체), one(하나) 아주 직관적인 이름으로 되어 있어서 구분을 쉽게 할 수 있네요.

이제 학번으로 검색을 했을 때 fetchone()으로하나의 데이터만 나오게 해 봅시다. 

SELECT 쿼리의 WHERE 절을 사용해서 바로 사용 해 봅시다.

import sqlite3
conn = sqlite3.connect('mydb.db')

# Cursor 객체 생성
c = conn.cursor()

# 학번을 검색해서 정보 출력
num = ('20201234',)
c.execute('SELECT * FROM student WHERE num = ?', num)
print(c.fetchone())

# 접속한 db 닫기
conn.close()

 

위에서 학번을 튜플(tuple)로 전달을 해야 합니다. 파이썬에서 자료형을 다룰 때 튜플에 대해서 배웠습니다.

() 안에 데이터를 넣어서 저장하는 방식이죠. 튜플에 하나의 요소를 담을 때에는 뒤에 꼭 , 를 붙여야 하는 것만 알면 됩니다. 

num = ('20201234',) 를 변수에 담아서 전달해서 ? 에 맵핑(바인딩) 으로 사용합니다.

c.execute('SELECT * FROM student WHERE num = ?', ('20201234',)) 이렇게 바로 써도 무방합니다.

여러 개의 물음표를 쓴다면 

data = ('1234', 'abcd')

'? , ?', data  이런 식으로 쓸 수 있겠네요.

num = ('20201234','파이썬')
c.execute('SELECT * FROM student WHERE num = ? and name = ?', num)

여기서 중요한 것은 쿼리문을 파이썬에서 문자열 다룰 때 사용했던 '%s' % num 또는 {}.format(num) 이런 형식으로 사용할 경우 해커가 SQL 인젝션 공격을 하게 됩니다. 보안상 execute 함수에서 바인딩해서 사용합니다. sqlite 에서는 ?를 사용했지만 다른 패키지(모듈)에서는 ?는 %s로 바뀔 수 있습니다.

위 내용을 다시 정리하면

query  = '쿼리문%s' % '%s위치에 들어갈 데이터'

execute(query)

이렇게 쓰지 말고

query  = '쿼리문 ?' 또는 '쿼리문 %s'

execute(query, '? 또는 %s에 들어갈 데이터')

는 이야기입니다.

 

위 내용을 참고하여 우리 Flask 프로젝트에 적용시켜 브라우저에서 사용자가 입력한 학번과 이름을 저장이 되게 만들어 봅시다.

 

간단하게  sqlite를 사용하는 방법에 대해서 알아봤습니다.

파이썬에서 Class로 데이터 모델 객체와 데이터베이스와 연결해서 사용하는 ORM이라는 것도 있으니 알아 두면 좋습니다. 

 

 

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함