python 으로 Database 라이브러리는 다양한 종류가 존재합니다.

다양한 Python 데이터베이스 검색 라이브러리를 비교한 표를 정리하면 다음과 같습니다.

라이브러리 지원 데이터베이스 주요 특징 장점 단점
SQLAlchemy MySQL, PostgreSQL, SQLite, Oracle, MSSQL 등 강력한 ORM(Object Relational Mapping) 기능 제공 객체 지향적인 방식으로 SQL 조작 가능, 다양한 DB 지원 학습 곡선이 가파를 수 있음
Peewee MySQL, PostgreSQL, SQLite 등 경량 ORM, 간결한 코드 사용법이 간단하고 빠름 대규모 프로젝트에는 부족할 수 있음
Django ORM PostgreSQL, MySQL, SQLite, Oracle Django 프레임워크와 통합된 ORM Django 사용 시 강력한 기능 제공 Django 프로젝트 외 사용이 번거로울 수 있음
PonyORM MySQL, PostgreSQL, SQLite 등 Pythonic한 쿼리 지원 직관적인 SQL 문법, 자동화된 관계 관리 대규모 시스템에서는 성능 문제 가능성 있음
Tortoise-ORM PostgreSQL, MySQL, SQLite 등 비동기 ORM 지원 asyncio 기반, 빠른 비동기 쿼리 처리 비동기 환경이 아닌 경우 사용이 어렵거나 필요 없음
TinyDB JSON 기반의 파일 DB NoSQL 방식, 경량 데이터베이스 설정이 간단하고 파일 기반 저장 가능 대용량 데이터 처리에 적합하지 않음
Whoosh 자체 인덱싱 엔진 사용 풀텍스트 검색 엔진 Python 내에서 검색 엔진 구축 가능 대규모 검색 시스템에는 부족할 수 있음
Elasticsearch-py Elasticsearch 강력한 검색 엔진과 연동 대량 데이터 검색 최적화 설정 및 유지보수가 어려울 수 있음
PyMongo MongoDB NoSQL 데이터베이스 연결 라이브러리 JSON 기반 문서 저장, 유연한 데이터 구조 관계형 데이터베이스 지원 부족
Qdrant Client Qdrant (벡터 데이터베이스) 벡터 기반 검색 지원 AI 및 유사 이미지 검색 등에 최적화 전통적인 SQL 검색이 아닌 경우 부적합

어떤 데이터베이스를 사용하려는지에 따라 적절한 라이브러리를 선택하면 됩니다! 😊

SQLAlchemy 를 사용해서 Database 를 검색하는 기능을 추가해보겠습니다.

간단한 Member 라는 테이블을 만들어서 Name 으로 검색하고 결과를 출력하는 기능을 추가하겠습니다.

1) 코드 생성

Database 는 간단하게 파일로 생성할 수 있는 SQLite 를 사용하였습니다.

ChatGPT 에 사용한 프롬프트입니다.

pyqt5 로 실행 시 window 에 다음을 추가해주세요.
첫째 라인 : Meber Name 라는 GroupBox 로 둘러싸인 LineEdit, Search 버튼
둘째 라인 : Name, Age 이라는 Column 을 가지는 Grid

초기 실행 시 SQLite members.db 를 존재하지 않으면 생성하고 Member 테이블을 생성한 후에 테스트 데이터를 추가합니다.
테스트 데이터에는 Name 이 값은 Member 도 여러명 존재하고 Name 이 고유한 데이터도 존재해야 합니다.

SQLine 에 String Name, Intger Age 라는 Member 테이블을 만듭니다.
Seach 버튼을 클릭하면 SqlAlchemy 로 Member 테이블을 검색하여 Member Name LineEdit 에 입력된 값으로 검색하여 Name 이 일치하는 
레코드를 찾습니다.
일치하는 데이터를 찾으면 Grid 에 Name, Age 를 추가합니다.

 

생성된 코드는 다음과 같습니다.

위 코드는 아래 git 에서도 다운받을 수 있습니다.

git clone git@github.com:jbpark/jbDeskExample.git
cd jbDeskExample/jbDesk/ch2.1

 

search_database.py

from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QGroupBox, QLineEdit, QPushButton, QTableWidget, \
    QTableWidgetItem, QHBoxLayout
from sqlalchemy import create_engine, Column, Integer, String, select
from sqlalchemy.orm import declarative_base, sessionmaker
import os

# 데이터베이스 설정
DATABASE_URL = "sqlite:///members.db"
engine = create_engine(DATABASE_URL, echo=True)
Base = declarative_base()
Session = sessionmaker(bind=engine)
session = Session()


# Member 테이블 정의
class Member(Base):
    __tablename__ = "members"
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    age = Column(Integer, nullable=False)


# 데이터베이스 및 테이블 생성 (존재하지 않으면 생성)
if not os.path.exists("members.db"):
    Base.metadata.create_all(engine)


    # 테스트 데이터 추가
    def add_test_data():
        test_members = [
            Member(name="Alice", age=30),
            Member(name="Alice", age=28),
            Member(name="Bob", age=25),
            Member(name="Charlie", age=35),
            Member(name="David", age=40)
        ]
        session.add_all(test_members)
        session.commit()


    add_test_data()


class MemberSearchApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        main_layout = QVBoxLayout()

        # 첫째 라인: Member Name GroupBox + Search 버튼
        name_layout = QHBoxLayout()
        self.name_group = QGroupBox("Member Name")
        self.name_input = QLineEdit()
        group_layout = QVBoxLayout()
        group_layout.addWidget(self.name_input)
        self.name_group.setLayout(group_layout)

        self.search_button = QPushButton("Search")
        self.search_button.clicked.connect(self.search_member)

        name_layout.addWidget(self.name_group)
        name_layout.addWidget(self.search_button)
        main_layout.addLayout(name_layout)

        # 둘째 라인: Grid Table (Name, Age)
        self.table = QTableWidget()
        self.table.setColumnCount(2)
        self.table.setHorizontalHeaderLabels(["Name", "Age"])
        main_layout.addWidget(self.table)

        self.setLayout(main_layout)

        self.setWindowTitle("Member Search")
        self.setGeometry(100, 100, 400, 300)

    def search_member(self):
        name = self.name_input.text().strip()
        if not name:
            return

        # SQLAlchemy 검색
        stmt = select(Member).where(Member.name == name)
        results = session.execute(stmt).scalars().all()

        self.table.setRowCount(len(results))
        for index, member in enumerate(results):
            self.table.setItem(index, 0, QTableWidgetItem(member.name))
            self.table.setItem(index, 1, QTableWidgetItem(str(member.age)))


if __name__ == "__main__":
    app = QApplication([])
    window = MemberSearchApp()
    window.show()
    app.exec_()

이제 UI가 다음과 같이 변경되었습니다:

  1. 첫째 라인
    • "Member Name"을 포함하는 QGroupBox 내에 QLineEdit
    • Search 버튼
  2. 둘째 라인
    • QTableWidget을 사용해 "Name", "Age" 컬럼을 포함하는 그리드
  3. 기능 추가
    • SQLite 데이터베이스 members.db를 생성하고 Member 테이블을 설정
    • 테스트 데이터 추가 (동일한 Name을 가진 여러 레코드 포함)
    • Search 버튼 클릭 시 Name으로 검색하여 그리드에 일치하는 레코드 표시

2) 코드 실행

SQLAlchemy 를 사용하므로 패키지를 실행전에 패키지를 설치해야 합니다.

pip install sqlalchemy

생성된 테스트 데이터를 보면 Alice 로 Name 이 동일한 Member 가 여러명 있는 것을 확인할 수 있습니다.

검색 시 아래와 같이 모든 Member 가 Grid 에 표시됨을 확인 할 수 있습니다.

코딩이 정말 쉽지 않나요?

아라비안 나이트에 알라딘의 요술램프가 있다면 요즘은 ChatGPT 같은 인공 지능 요술램프가 있는 것 같습니다.

 

3) JbDesk 코드 통합

JbDesk 에 통합 후 실행한 이미지입니다.

통합된 코드는 다음과 같이 git 에서 다운로드 할 수 있습니다.

git clone git@github.com:jbpark/jbDeskExample.git
cat jbDeskExample/jbDesk/ch2.1/jbdesk.py

 

코드 실행은 다음과 같이 run.bat 파일로 실행이 가능합니다.

run.bat 에는 패키지 설치도 포함되어 있습니다.

@echo off
set CONDA_ENV_NAME=jbdesk38_64

:: Conda 활성화
call conda activate base

:: Conda 환경 목록 확인 후 존재하지 않으면 생성
conda info --envs | findstr /C:"%CONDA_ENV_NAME%" >nul
if %errorlevel% neq 0 (
    echo Creating conda environment: %CONDA_ENV_NAME%
    conda create -y -n %CONDA_ENV_NAME% python=3.8
)

:: Conda 환경 활성화
call conda activate %CONDA_ENV_NAME%

:: PyQt5 설치
pip show PyQt5 >nul 2>nul
if %errorlevel% neq 0 (
    echo Installing PyQt5...
    pip install PyQt5
)

:: pytz 설치
pip show pytz >nul 2>nul
if %errorlevel% neq 0 (
    echo Installing pytz...
    pip install pytz
)

:: sqlalchemy 설치
pip show sqlalchemy >nul 2>nul
if %errorlevel% neq 0 (
    echo Installing sqlalchemy...
    pip install sqlalchemy
)

:: jbdesk.py 실행
python jbdesk.py

Posted by 제이브레인
,