[Python MongoDB] pymongo - CRUD 작업

2024. 11. 29. 10:30·파이썬/Package
반응형

소개

MongoDB는 강력한 NoSQL 데이터베이스이며, pymongo는 Python에서 MongoDB를 사용할 수 있게 해주는 공식 드라이버입니다. 이번 글에서는 pymongo를 사용하여 데이터를 다루는 다양한 방법을 자세히 알아보겠습니다.

MongoDB 연결 설정

from pymongo import MongoClient
from pymongo.collection import Collection
from pymongo.database import Database
from typing import Optional, Dict, List

class MongoDBManager:
    def __init__(self, uri: str, db_name: str):
        """
        MongoDB 연결 관리자

        Args:
            uri: MongoDB 연결 문자열
            db_name: 데이터베이스 이름

        Example:
            manager = MongoDBManager("mongodb://localhost:27017", "my_db")
        """
        self.client = MongoClient(uri)
        self.db: Database = self.client[db_name]

    def get_collection(self, collection_name: str) -> Collection:
        """특정 컬렉션 가져오기"""
        return self.db[collection_name]

    def close(self):
        """연결 종료"""
        self.client.close()

문서 삽입 (Insert)

단일 문서 삽입

from datetime import datetime

def insert_user(collection: Collection, user_data: Dict) -> str:
    """
    사용자 정보를 데이터베이스에 삽입

    Args:
        collection: MongoDB 컬렉션
        user_data: 삽입할 사용자 데이터

    Returns:
        생성된 문서의 ID

    Example:
        user = {
            "name": "John Doe",
            "email": "john@example.com",
            "created_at": datetime.now()
        }
        user_id = insert_user(db.users, user)
    """
    result = collection.insert_one(user_data)
    return str(result.inserted_id)

# 사용 예시
db = MongoDBManager("mongodb://localhost:27017", "my_db")
users = db.get_collection("users")

new_user = {
    "name": "John Doe",
    "email": "john@example.com",
    "age": 30,
    "created_at": datetime.now()
}

user_id = insert_user(users, new_user)
print(f"Created user with ID: {user_id}")

다중 문서 삽입

def insert_many_users(collection: Collection, users_data: List[Dict]) -> List[str]:
    """
    여러 사용자 정보를 한 번에 삽입

    Args:
        collection: MongoDB 컬렉션
        users_data: 삽입할 사용자 데이터 리스트

    Returns:
        생성된 문서들의 ID 리스트

    Example:
        users = [
            {"name": "John", "email": "john@example.com"},
            {"name": "Jane", "email": "jane@example.com"}
        ]
        user_ids = insert_many_users(db.users, users)
    """
    result = collection.insert_many(users_data)
    return [str(id) for id in result.inserted_ids]

문서 조회 (Find)

단일 문서 조회

from bson.objectid import ObjectId

def find_user_by_id(collection: Collection, user_id: str) -> Optional[Dict]:
    """
    ID로 사용자 조회

    Example:
        user = find_user_by_id(db.users, "507f1f77bcf86cd799439011")
    """
    return collection.find_one({"_id": ObjectId(user_id)})

def find_user_by_email(collection: Collection, email: str) -> Optional[Dict]:
    """
    이메일로 사용자 조회

    Example:
        user = find_user_by_email(db.users, "john@example.com")
    """
    return collection.find_one({"email": email})

다중 문서 조회

def find_users(
    collection: Collection,
    query: Dict = None,
    sort_by: str = None,
    limit: int = None
) -> List[Dict]:
    """
    조건에 맞는 사용자들 조회

    Example:
        # 30세 이상 사용자 조회
        users = find_users(db.users, {"age": {"$gte": 30}})

        # 이름으로 정렬하여 조회
        users = find_users(db.users, sort_by="name")
    """
    cursor = collection.find(query or {})

    if sort_by:
        cursor = cursor.sort(sort_by)

    if limit:
        cursor = cursor.limit(limit)

    return list(cursor)

문서 수정 (Update)

단일 문서 수정

def update_user(
    collection: Collection,
    user_id: str,
    update_data: Dict
) -> bool:
    """
    사용자 정보 수정

    Example:
        success = update_user(
            db.users,
            "507f1f77bcf86cd799439011",
            {"$set": {"age": 31}}
        )
    """
    result = collection.update_one(
        {"_id": ObjectId(user_id)},
        {"$set": update_data}
    )
    return result.modified_count > 0

# 증가/감소 연산
def increment_user_age(collection: Collection, user_id: str) -> bool:
    """
    사용자 나이 1 증가
    """
    result = collection.update_one(
        {"_id": ObjectId(user_id)},
        {"$inc": {"age": 1}}
    )
    return result.modified_count > 0

다중 문서 수정

def update_many_users(
    collection: Collection,
    query: Dict,
    update_data: Dict
) -> int:
    """
    조건에 맞는 여러 사용자 정보 수정

    Returns:
        수정된 문서 수

    Example:
        # 30세 이상 사용자의 상태를 'active'로 변경
        modified_count = update_many_users(
            db.users,
            {"age": {"$gte": 30}},
            {"$set": {"status": "active"}}
        )
    """
    result = collection.update_many(query, {"$set": update_data})
    return result.modified_count

문서 삭제 (Delete)

def delete_user(collection: Collection, user_id: str) -> bool:
    """
    사용자 삭제

    Example:
        success = delete_user(db.users, "507f1f77bcf86cd799439011")
    """
    result = collection.delete_one({"_id": ObjectId(user_id)})
    return result.deleted_count > 0

def delete_many_users(collection: Collection, query: Dict) -> int:
    """
    조건에 맞는 여러 사용자 삭제

    Example:
        # 비활성 사용자 모두 삭제
        deleted_count = delete_many_users(
            db.users,
            {"status": "inactive"}
        )
    """
    result = collection.delete_many(query)
    return result.deleted_count

고급 쿼리 작업

집계 (Aggregation)

def get_user_stats(collection: Collection) -> Dict:
    """
    사용자 통계 정보 조회

    Example:
        stats = get_user_stats(db.users)
        # {"total_users": 100, "avg_age": 35.5}
    """
    pipeline = [
        {
            "$group": {
                "_id": None,
                "total_users": {"$sum": 1},
                "avg_age": {"$avg": "$age"}
            }
        }
    ]

    result = list(collection.aggregate(pipeline))
    return result[0] if result else {}

인덱스 관리

def ensure_indexes(collection: Collection):
    """
    필요한 인덱스 생성
    """
    # 이메일 unique 인덱스
    collection.create_index("email", unique=True)
    # 나이 + 이름 복합 인덱스
    collection.create_index([("age", 1), ("name", 1)])

배치 작업 처리

from typing import List

def batch_process_users(
    collection: Collection,
    operations: List[Dict],
    batch_size: int = 1000
):
    """
    대량의 사용자 정보 일괄 처리

    Example:
        operations = [
            {
                "type": "update",
                "query": {"_id": ObjectId("...")},
                "update": {"$set": {"status": "active"}}
            },
            {
                "type": "insert",
                "document": {"name": "New User", "email": "new@example.com"}
            }
        ]
        batch_process_users(db.users, operations)
    """
    for i in range(0, len(operations), batch_size):
        batch = operations[i:i + batch_size]
        bulk_operations = []

        for op in batch:
            if op["type"] == "update":
                bulk_operations.append(
                    UpdateOne(op["query"], op["update"])
                )
            elif op["type"] == "insert":
                bulk_operations.append(
                    InsertOne(op["document"])
                )

        if bulk_operations:
            collection.bulk_write(bulk_operations, ordered=False)

예외 처리

from pymongo.errors import (
    DuplicateKeyError,
    ConnectionError,
    OperationFailure
)

def safe_insert_user(collection: Collection, user_data: Dict) -> Optional[str]:
    """
    예외 처리가 포함된 안전한 사용자 삽입
    """
    try:
        result = collection.insert_one(user_data)
        return str(result.inserted_id)
    except DuplicateKeyError:
        print("이미 존재하는 사용자입니다.")
    except ConnectionError:
        print("데이터베이스 연결 오류")
    except OperationFailure as e:
        print(f"작업 실패: {str(e)}")
    return None

마치며

pymongo를 사용하면 Python에서 MongoDB를 효율적으로 다룰 수 있습니다. 기본적인 CRUD 작업부터 복잡한 집계 작업까지, pymongo는 MongoDB의 모든 기능을 Python에서 사용할 수 있게 해줍니다. 대량의 데이터를 처리할 때는 배치 작업을 활용하고, 적절한 예외 처리를 통해 안정적인 애플리케이션을 구축할 수 있습니다.

저작자표시 비영리 변경금지 (새창열림)

'파이썬 > Package' 카테고리의 다른 글

Hugging Face Transformers: pipeline으로 AI 모델 쉽게 사용하기  (0) 2025.04.03
aiohttp.ClientSession: 비동기 HTTP 클라이언트 세션  (1) 2024.11.04
PyInstaller : Python 애플리케이션 빌드 도구  (0) 2024.10.31
OpenPyXL을 이용한 Python에서의 엑셀 파일 생성  (0) 2024.09.19
Auto Py to Exe: 쉬운 실행 파일 생성  (0) 2024.09.10
'파이썬/Package' 카테고리의 다른 글
  • Hugging Face Transformers: pipeline으로 AI 모델 쉽게 사용하기
  • aiohttp.ClientSession: 비동기 HTTP 클라이언트 세션
  • PyInstaller : Python 애플리케이션 빌드 도구
  • OpenPyXL을 이용한 Python에서의 엑셀 파일 생성
코샵
코샵
나의 코딩 일기장
    반응형
  • 코샵
    끄적끄적 코딩 공방
    코샵
  • 전체
    오늘
    어제
    • 분류 전체보기 (529) N
      • 상품 추천 (41)
      • MongoDB (4)
      • 하드웨어 (9) N
      • 일기장 (4)
      • Unity (138)
        • Tip (41)
        • Project (1)
        • Design Pattern (8)
        • Firebase (6)
        • Asset (2)
      • 파이썬 (127)
        • Basic (40)
        • OpenCV (8)
        • Pandas (15)
        • PyQT (3)
        • SBC(Single Board Computer) (1)
        • 크롤링 (14)
        • Fast API (29)
        • Package (6)
      • Linux (4)
      • C# (97)
        • Algorithm (11)
        • Window (7)
      • TypeScript (48)
        • CSS (10)
      • Git (11)
      • SQL (5)
      • Flutter (10)
        • Tip (1)
      • System (1)
      • BaekJoon (6)
      • Portfolio (2)
      • MacOS (1)
      • 유틸리티 (1)
      • 서비스 (6)
      • 자동화 (3)
      • Hobby (10)
        • 물생활 (10)
        • 식집사 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 다비즈
  • 공지사항

  • 인기 글

  • 태그

    codingtips
    라떼우유
    쇼핑몰리뷰
    리뷰이관
    appdevelopment
    카페24리뷰
    rtsp
    devlife
    셀레니움
    Python
    codingcommunity
    카페24리뷰이관
    파이썬
    C#
    list
    learntocode
    스크립트 실행 순서
    유니티
    긴유통기한우유
    리뷰관리
    리스트
    스크립트 실행
    상품 리뷰 크롤링
    programmerlife
    믈레코비타멸균우유
    programming101
    unity
    cv2
    ipcamera
    스마트스토어리뷰
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
코샵
[Python MongoDB] pymongo - CRUD 작업
상단으로

티스토리툴바