프로그래밍/Python

Python에서 데이터베이스 처리: SQLite와 ORM(SQLAlchemy) 비교

shimdh 2025. 2. 22. 09:12
728x90

1. SQLite: 경량 데이터베이스의 강자

1.1 SQLite란?

SQLite는 파일 기반의 경량 관계형 데이터베이스 관리 시스템(RDBMS)입니다. 서버 설치 없이 단일 파일로 데이터를 관리할 수 있어, 소규모 애플리케이션이나 프로토타입 개발에 적합합니다. Python에서는 sqlite3 모듈을 통해 SQLite를 쉽게 사용할 수 있습니다. SQLite는 특히 모바일 애플리케이션, 임베디드 시스템, 그리고 소규모 웹 애플리케이션에서 널리 사용됩니다.

1.2 SQLite의 주요 특징

  • 파일 기반: 모든 데이터가 단일 파일에 저장되어 이동성이 뛰어납니다. 이는 데이터베이스를 쉽게 백업하거나 다른 시스템으로 이동할 수 있게 해줍니다.
  • 경량성: 다른 RDBMS보다 메모리와 디스크 공간을 적게 차지합니다. 이는 리소스가 제한된 환경에서 매우 유용합니다.
  • 내장형: Python 표준 라이브러리에 포함되어 있어 별도의 설치가 필요 없습니다. 이는 개발 환경을 빠르게 설정할 수 있게 해줍니다.
  • ACID 준수: 원자성, 일관성, 고립성, 지속성을 보장하여 안정적인 트랜잭션 처리가 가능합니다. 이는 데이터 무결성을 유지하는 데 매우 중요합니다.

1.3 SQLite 기본 사용법

SQLite를 사용하려면 sqlite3 모듈을 import하고 데이터베이스 파일에 연결하면 됩니다. 아래는 기본적인 사용 예시입니다.

import sqlite3

# 데이터베이스 연결 (없으면 생성)
conn = sqlite3.connect('example.db')

# 커서 객체 생성
cursor = conn.cursor()

# 테이블 생성
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY,
    name TEXT,
    age INTEGER
)
''')

# 데이터 삽입
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Alice', 30))
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Bob', 25))

# 변경사항 저장
conn.commit()

# 데이터 조회
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall()
for row in rows:
    print(row)

# 연결 종료
conn.close()

위 코드는 example.db 파일에 users 테이블을 생성하고 데이터를 삽입한 후 조회하는 과정을 보여줍니다. 이 예제는 SQLite의 기본적인 사용법을 이해하는 데 도움이 됩니다.

1.4 SQLite에서의 CRUD 작업

CRUD(Create, Read, Update, Delete) 작업은 데이터베이스에서 가장 기본적인 작업입니다. SQLite에서 이러한 작업을 수행하는 방법은 다음과 같습니다.

  • Create (생성)

    cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Charlie', 28))
    conn.commit()
  • Read (조회)

    cursor.execute("SELECT * FROM users WHERE age > ?", (25,))
    rows = cursor.fetchall()
    for row in rows:
      print(row)
  • Update (수정)

    cursor.execute("UPDATE users SET age = ? WHERE name = ?", (31, 'Alice'))
    conn.commit()
  • Delete (삭제)

    cursor.execute("DELETE FROM users WHERE name = ?", ('Bob',))
    conn.commit()

각 작업 후에는 반드시 conn.commit()을 호출하여 변경 사항을 데이터베이스에 적용해야 합니다.

1.5 SQLite 예외 처리

데이터베이스 작업 중 오류가 발생할 수 있으므로 예외 처리를 통해 안정성을 높이는 것이 중요합니다.

try:
    # DB 작업 코드...
except sqlite3.Error as e:
    print(f"An error occurred: {e}")
finally:
    if conn:
        conn.close()

이렇게 하면 에러 발생 시에도 연결이 안전하게 종료됩니다.


2. ORM: SQLAlchemy를 통한 객체 지향 데이터베이스 처리

2.1 ORM이란?

ORM(Object-Relational Mapping)은 객체 지향 프로그래밍 언어와 관계형 데이터베이스 간의 상호작용을 쉽게 해주는 기술입니다. SQLAlchemy는 Python에서 가장 널리 사용되는 ORM 라이브러리 중 하나로, SQL 쿼리를 직접 작성하지 않고도 데이터베이스와 상호작용할 수 있습니다. ORM은 특히 대규모 프로젝트에서 코드의 가독성과 유지보수성을 높이는 데 큰 도움이 됩니다.

2.2 ORM의 장점

  • 코드 가독성 향상: SQL 문법 대신 파이썬 객체를 사용합니다. 이는 코드를 더 직관적으로 만들어줍니다.
  • 유지보수 용이: 데이터 구조 변경 시 코드 수정이 최소화됩니다. 이는 대규모 프로젝트에서 매우 중요합니다.
  • 보안 강화: 자동으로 쿼리 파라미터화를 통해 SQL Injection을 방지합니다. 이는 보안을 강화하는 데 큰 도움이 됩니다.

2.3 SQLAlchemy 기본 사용법

SQLAlchemy를 사용하려면 먼저 설치해야 합니다.

pip install sqlalchemy

그 다음, 아래와 같이 데이터베이스와 모델을 정의할 수 있습니다.

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

# SQLite 메모리 내 DB 생성
engine = create_engine('sqlite:///:memory:')
Base = declarative_base()

# 사용자 모델 정의
class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    age = Column(Integer)

# 테이블 생성
Base.metadata.create_all(engine)

# 세션 만들기 
Session = sessionmaker(bind=engine)
session = Session()

위 코드는 User 클래스를 정의하고 SQLite 메모리 내 데이터베이스에 users 테이블을 생성합니다.

2.4 CRUD 작업 수행하기

SQLAlchemy에서 CRUD 작업은 매우 직관적입니다.

  • Create (생성)

    new_user = User(name="Alice", age=30)
    session.add(new_user)
    session.commit()
  • Read (조회)

    user_list = session.query(User).all()
    for user in user_list:
      print(f'ID: {user.id}, Name: {user.name}, Age: {user.age}')
  • Update (수정)

    alice = session.query(User).filter_by(name="Alice").first()
    alice.age += 1  # 나이를 증가시킴
    session.commit()
  • Delete (삭제)

    session.delete(alice)
    session.commit()

2.5 복잡한 쿼리 및 관계 설정

SQLAlchemy에서는 여러 테이블 간의 관계도 쉽게 설정할 수 있습니다. 예를 들어, UserAddress 테이블 간의 일대다 관계를 설정할 수 있습니다.

from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship

class Address(Base):
    __tablename__ = 'addresses'

    id = Column(Integer, primary_key=True)
    email_address = Column(String, nullable=False)
    user_id = Column(Integer, ForeignKey('users.id'))

# 관계 설정
User.addresses = relationship("Address", back_populates="user")
Address.user = relationship("User", back_populates="addresses")

이렇게 설정하면 User 객체를 통해 관련된 Address 객체에 쉽게 접근할 수 있습니다.


3. SQLite vs ORM: 언제 무엇을 사용할까?

3.1 SQLite를 사용하는 경우

  • 소규모 프로젝트: 간단한 데이터 저장이 필요할 때.
  • 테스트 환경: 빠르게 프로토타입을 만들고 테스트할 때.
  • 파일 기반 데이터베이스: 서버 설정 없이 파일로 데이터를 관리하고 싶을 때.

3.2 ORM(SQLAlchemy)을 사용하는 경우

  • 대규모 프로젝트: 복잡한 데이터 구조와 관계를 다룰 때.
  • 객체 지향 설계: SQL 쿼리보다 파이썬 객체를 사용하고 싶을 때.
  • 유지보수 용이성: 코드의 가독성과 유지보수를 중요시할 때.

4. 결론

SQLite와 ORM(SQLAlchemy)은 각각의 장단점이 있으며, 프로젝트의 규모와 요구사항에 따라 적절히 선택해야 합니다. SQLite는 간단하고 빠르게 데이터를 관리할 때 유용하고, ORM은 복잡한 데이터 구조와 객체 지향 설계가 필요한 경우에 적합합니다. 두 도구를 잘 활용하면 Python 프로젝트의 데이터베이스 처리를 더욱 효율적으로 할 수 있습니다.


추가 학습을 위한 팁

  • SQLite 공식 문서: https://www.sqlite.org/docs.html
  • SQLAlchemy 공식 문서: https://docs.sqlalchemy.org/
  • 실습 프로젝트: 간단한 블로그 애플리케이션을 만들어보며 SQLite와 SQLAlchemy를 모두 사용해보세요. 이를 통해 두 기술의 차이점을 더 깊이 이해할 수 있습니다.

5. 심화 학습: SQLite와 SQLAlchemy의 고급 기능

5.1 SQLite의 고급 기능

SQLite는 단순하면서도 강력한 기능을 제공합니다. 예를 들어, 트랜잭션 관리, 트리거, 뷰, 인덱스 등을 지원합니다. 이러한 기능을 활용하면 더 복잡한 데이터베이스 작업을 수행할 수 있습니다.

  • 트랜잭션 관리: SQLite는 트랜잭션을 통해 데이터의 일관성을 유지합니다. BEGIN, COMMIT, ROLLBACK을 사용하여 트랜잭션을 관리할 수 있습니다.
  • 트리거: 특정 이벤트가 발생할 때 자동으로 실행되는 SQL 코드를 정의할 수 있습니다.
  • : 복잡한 쿼리를 뷰로 저장하여 간단하게 사용할 수 있습니다.
  • 인덱스: 데이터 조회 속도를 높이기 위해 인덱스를 생성할 수 있습니다.

5.2 SQLAlchemy의 고급 기능

SQLAlchemy는 ORM 외에도 SQL 표현식 언어를 제공하여 복잡한 쿼리를 작성할 수 있습니다. 또한, 데이터베이스 마이그레이션, 연결 풀링, 비동기 지원 등 다양한 고급 기능을 제공합니다.

  • SQL 표현식 언어: SQLAlchemy는 SQL 쿼리를 파이썬 코드로 작성할 수 있는 강력한 표현식 언어를 제공합니다.
  • 데이터베이스 마이그레이션: Alembic을 사용하여 데이터베이스 스키마를 버전 관리하고 마이그레이션할 수 있습니다.
  • 연결 풀링: 데이터베이스 연결을 효율적으로 관리하여 성능을 최적화할 수 있습니다.
  • 비동기 지원: asyncio와 통합하여 비동기 데이터베이스 작업을 수행할 수 있습니다.

6. 실제 프로젝트에서의 활용 예시

6.1 SQLite를 사용한 프로젝트 예시

  • 개인 프로젝트: 간단한 할 일 목록 애플리케이션을 만들 때 SQLite를 사용할 수 있습니다. 파일 기반이기 때문에 배포와 관리가 쉽습니다.
  • 모바일 애플리케이션: 모바일 앱에서 로컬 데이터를 저장할 때 SQLite를 사용할 수 있습니다. 경량성과 내장형 특성이 모바일 환경에 적합합니다.

6.2 SQLAlchemy를 사용한 프로젝트 예시

  • 웹 애플리케이션: Flask나 Django와 같은 웹 프레임워크와 함께 SQLAlchemy를 사용하여 복잡한 데이터베이스 작업을 수행할 수 있습니다.
  • 대규모 프로젝트: 여러 테이블 간의 복잡한 관계를 다루는 대규모 프로젝트에서 SQLAlchemy를 사용하면 코드의 가독성과 유지보수성을 높일 수 있습니다.

7. 마무리

SQLite와 SQLAlchemy는 각각의 장단점이 있으며, 프로젝트의 요구사항에 따라 적절히 선택해야 합니다. SQLite는 간단하고 빠르게 데이터를 관리할 때 유용하고, SQLAlchemy는 복잡한 데이터 구조와 객체 지향 설계가 필요한 경우에 적합합니다. 두 도구를 잘 활용하면 Python 프로젝트의 데이터베이스 처리를 더욱 효율적으로 할 수 있습니다.

728x90