파이썬은 강력한 표준 라이브러리 덕분에, 외부 프레임워크인 Django ORM 없이도 데이터베이스를 쉽게 생성하고 조작할 수 있는 기능을 내장하고 있습니다.
SQLite는 가볍고 파이썬과 호환성이 뛰어나, 데이터베이스 프로그래밍의 기본 원리를 학습하는 데 적합합니다. 간단한 사용자 등록 애플리케이션을 통해 파이썬에서 데이터베이스를 어떻게 다루는지 살펴보겠습니다.
파이썬에서 데이터베이스 생성하기
파이썬에서 데이터베이스를 만들고 상호 작용하기 위해서는 ‘연결’과 ‘커서’라는 두 가지 핵심 요소가 필요합니다.
연결은 기존 데이터베이스에 접속하거나 새로운 데이터베이스를 생성하는 데 사용됩니다. 다음은 SQLite를 활용하여 파이썬에서 데이터베이스 연결을 설정하는 방법입니다:
import sqlite3conn = sqlite3.connect('경로/데이터베이스.db')
conn.close()
connect()
메서드는 데이터베이스 파일의 경로를 인자로 받습니다. 만약 지정된 경로에 데이터베이스 파일이 없다면, 이 메서드는 새로운 데이터베이스 파일을 생성합니다. 데이터베이스와의 모든 작업이 완료되면 반드시 연결을 종료해야 합니다.
커서는 연결된 데이터베이스와 상호 작용하는 데 사용되며, SQL 쿼리를 실행할 수 있게 해줍니다. 커서를 생성하는 방법은 다음과 같습니다:
cursor = conn.cursor()cursor.close()
cursor()
메서드는 활성화된 연결 객체에서 호출되어 커서 객체를 반환합니다.
파이썬에서 데이터베이스 트랜잭션 실행하기
커서를 통해 SQL 구문, 쿼리, 또는 스크립트를 실행하여 데이터를 읽고 쓰고 데이터베이스 구조를 변경할 수 있습니다.
데이터베이스 트랜잭션을 실행하는 데 사용되는 세 가지 주요 방법은 다음과 같습니다:
cursor.execute
: 이 메서드는 단일 SQL 구문을 실행합니다. 예시는 다음과 같습니다:cursor.execute(""" CREATE TABLE IF NOT EXISTS users ( name TEXT, age INTEGER ) """)
이 코드는 커서 객체의
execute
메서드를 호출하여 SQL 구문 문자열을 전달합니다.cursor.executemany
: 이 메서드는 동일한 SQL 구문을 여러 번 실행할 때, 각 실행마다 다른 매개변수를 사용할 수 있게 해줍니다. SQL 구문과 반복 가능한(iterable) 객체 두 개의 인자를 받습니다. 이는 여러 객체를 데이터베이스에 한 번에 삽입하는 데 유용합니다.data = [ ('Alice', 25), ('Bob', 30), ('Charlie', 22) ]
cursor.executemany("""INSERT INTO users (name, age) VALUES (?, ?)""", data)
위 코드는
executemany
메서드를 사용하여 여러 값을 데이터베이스에 삽입합니다.?
는 SQL 구문 내의 자리 표시자 역할을 하며,executemany
메서드는 이를 반복 객체의 값으로 치환합니다.cursor.executescript
: 이 메서드는 SQL 스크립트를 실행합니다. SQL 구문을 별도의 파일에 작성한 후executescript
메서드를 사용하여 실행할 수 있습니다.with open("경로/스크립트.sql") as file: sql_script = file.read()
cursor.executescript(sql_script)
파이썬과 SQLite3를 이용한 등록 앱 개발
등록 앱의 핵심 로직은 사용자 정보를 파이썬으로 받아 데이터베이스에 저장하는 것입니다. 다음은 파이썬과 SQLite3를 사용하여 간단한 등록 시스템을 구현하는 단계를 설명합니다.
1단계: 기존 데이터베이스 연결 또는 새 데이터베이스 생성
먼저, 애플리케이션에 사용할 데이터베이스를 생성하거나 기존 데이터베이스에 연결합니다.
import sqlite3conn = sqlite3.connect('database.db')
cursor = conn.cursor()
cursor.close()
conn.close()
위 코드는 데이터베이스와의 상호 작용을 위한 연결 객체와 커서를 생성합니다.
2단계: 사용자 테이블 생성
사용자가 제공하는 데이터를 저장할 테이블이 필요합니다. 다음은 커서를 사용하여 테이블을 생성하는 방법입니다:
cursor.execute(""" CREATE TABLE IF NOT EXISTS users ( first_name TEXT, last_name TEXT, email TEXT UNIQUE, password TEXT ) """)conn.commit()
이 코드는 데이터베이스에 ‘users’ 테이블이 없을 경우 새로 생성합니다. 테이블에는 사용자 정보를 저장하기 위한 네 개의 열이 있으며, 이메일 필드는 중복 계정 생성을 방지하기 위해 고유하게 설정되었습니다.
conn.commit()
호출은 데이터베이스 변경사항을 저장하는 데 중요합니다. 이 호출이 없다면 변경사항은 데이터베이스에 반영되지 않습니다.
만약 executescript
메서드를 사용한다면, SQL 파일의 마지막에 COMMIT
키워드를 추가함으로써 conn.commit()
호출을 생략할 수 있습니다.
3단계: 사용자 데이터 수집
코드 재사용성을 높이기 위해 사용자 등록 기능을 처리하는 파이썬 함수를 만드는 것이 좋습니다. 이 함수는 사용자의 이름, 성, 이메일, 비밀번호를 수집합니다.
def register_user(): first_name = input("이름을 입력하세요: ") last_name = input("성을 입력하세요: ") email = input("이메일을 입력하세요: ") password1 = input("비밀번호를 입력하세요: ") password2 = input("비밀번호를 다시 입력하세요: ")
4단계: 비밀번호 확인
사용자가 비밀번호를 두 번 입력하도록 register_user
함수를 수정합니다. 입력한 비밀번호가 일치하지 않으면 비밀번호를 다시 입력하도록 요청해야 합니다. 이를 위해 다음 루프를 사용합니다.
def register_user(): first_name = input("이름을 입력하세요: ") last_name = input("성을 입력하세요: ") email = input("이메일을 입력하세요: ")while True:
password1 = input("비밀번호를 입력하세요: ")
password2 = input("비밀번호를 다시 입력하세요: ")
if password1 == password2:
print("성공적으로 등록되었습니다!")
break
else:
print("비밀번호가 일치하지 않습니다.")
변경된 코드를 통해 사용자는 일치하는 비밀번호를 입력해야만 등록을 완료할 수 있습니다.
5단계: 이메일 고유성 확인
사용자 테이블을 생성하는 SQL 구문에서 이메일 필드는 고유하도록 정의되어 있습니다. 이는 사용자가 이미 존재하는 이메일을 사용하여 가입하려고 시도할 경우 데이터베이스에서 오류가 발생한다는 것을 의미합니다. 따라서 오류를 적절하게 처리하기 위해 파이썬 예외 처리를 사용해야 합니다.
def register_user(): first_name = input("이름을 입력하세요: ") last_name = input("성을 입력하세요: ")while True:
email = input("이메일을 입력하세요: ")
password1 = input("비밀번호를 입력하세요: ")
password2 = input("비밀번호를 다시 입력하세요: ")
if password1 == password2:
try:
print("계정이 성공적으로 생성되었습니다.")
break
except sqlite3.IntegrityError:
print("오류: 이미 등록된 이메일입니다.")
else:
print("비밀번호가 일치하지 않습니다.")
이 코드는 try-except
블록을 사용하여 이메일 중복으로 인해 발생하는 오류를 처리합니다. 데이터베이스에서 IntegrityError
가 발생하면 while
루프가 계속되어 사용자에게 다른 이메일 주소를 입력하라는 메시지를 표시합니다.
이 예제 앱에서는 이메일 주소 중복으로 인해 IntegrityError
가 발생한다고 가정해도 무방하지만, 실제 애플리케이션에서는 발생할 수 있는 다양한 오류를 처리하기 위해 보다 정교한 오류 처리 방법을 사용하는 것이 좋습니다.
6단계: 데이터베이스에 사용자 데이터 삽입
이제 사용자 데이터를 수집하고 확인했으므로 데이터베이스에 추가할 차례입니다. 이를 위해 SQL 쿼리를 사용할 수 있습니다. 다음은 수정된 try-except
블록입니다:
try: cursor.execute(""" INSERT INTO users (first_name, last_name, email, password) VALUES (?, ?, ?, ?) """, (first_name, last_name, email, password2))conn.commit()
print("계정이 성공적으로 생성되었습니다.")
break
except sqlite3.IntegrityError:
print("오류: 이미 등록된 이메일입니다.")
수정된 try-except
블록에서 커서는 SQL 삽입 연산을 실행하고, conn.commit()
메서드는 SQL 연산을 데이터베이스에 적용합니다.
위 단계를 모두 수행했다면 사용자를 등록하고 데이터를 데이터베이스에 저장하는 앱이 완성됩니다. 데이터베이스 내용을 확인하려면 다음과 같은 앱을 사용할 수 있습니다. SQLite용 DB 브라우저
컬렉션 타입 대신 데이터베이스 사용
간단한 데이터의 경우, 직접 코드를 작성하는 것이 더 쉬울 수 있지만, 애플리케이션의 규모가 커지고 데이터베이스가 복잡해지면 Django ORM과 같은 도구를 사용하여 작업을 단순화하는 것이 좋습니다.
데이터베이스 관련 기술을 계속 연습하고 싶다면, 등록 프로그램을 보완하는 로그인 시스템을 구현해보는 것을 추천합니다.