> 백엔드 개발 > 파이썬 튜토리얼 > SQLModel을 사용하여 Python에서 활성 레코드 패턴을 구현합니다

SQLModel을 사용하여 Python에서 활성 레코드 패턴을 구현합니다

Mary-Kate Olsen
풀어 주다: 2025-01-27 00:12:09
원래의
422명이 탐색했습니다.

Implementing the Active Record Pattern in Python with SQLModel

Python 개발자는 Ruby on Rails에서 Python으로 마이그레이션할 때 Active Record의 우아한 데이터베이스 상호 작용을 놓치는 경우가 많습니다. Python의 SQLAlchemy(따라서 SQLModel)는 기본적으로 다른 접근 방식을 취하지만 비슷한 패턴을 구현하여 유형 안전성을 유지하고 Python 모범 사례를 따르면서 Rails 스타일 모델의 편리성을 Python 애플리케이션에 적용할 수 있습니다.

활성 녹화 모드

Ruby on Rails에서 널리 사용되는 Active Record 패턴은 데이터베이스 레코드를 데이터베이스 조작 방법을 사용하는 객체로 처리합니다. 별도의 저장소 클래스나 데이터 액세스 개체(DAO)를 사용할 필요가 없으며, 모델 자체가 데이터베이스와 상호 작용하는 방법을 알고 있습니다.

예를 들어 Rails에서는 다음과 같이 작성할 수 있습니다.

<code class="language-ruby"># 查找记录
user = User.find(123)

# 更新记录
user.name = "New Name"
user.save

# 创建新记录
post = Post.create(title: "Hello World")</code>
로그인 후 복사

Python에서 SQLModel 사용

Python의 SQLModel은 이 모드를 직접 제공하지 않지만 이러한 공통 작업을 제공하는 기본 클래스를 사용하여 구현할 수 있습니다. 방법은 다음과 같습니다.

  1. CRUD 기반 모델

먼저 일반적인 CRUD 작업을 구현하는 기본 클래스를 만듭니다.

<code class="language-python">from typing import TypeVar, List, Optional, Tuple
from datetime import datetime
import uuid
from sqlmodel import SQLModel, Session, select
from sqlalchemy import func

T = TypeVar("T", bound="CRUDModel")

class CRUDModel(SQLModel):
    id: str = Field(
        default_factory=lambda: str(uuid.uuid4()),
        primary_key=True
    )
    created_at: datetime = Field(default_factory=datetime.utcnow)
    updated_at: datetime = Field(default_factory=datetime.utcnow)

    @classmethod
    def all(cls: type[T], session: Session) -> List[T]:
        statement = select(cls)
        return session.exec(statement).all()

    @classmethod
    def find(cls: type[T], session: Session, id: str) -> Optional[T]:
        statement = select(cls).where(cls.id == id)
        return session.exec(statement).first()

    @classmethod
    def create(cls: type[T], session: Session, **kwargs) -> T:
        db_obj = cls(**kwargs)
        session.add(db_obj)
        session.commit()
        session.refresh(db_obj)
        return db_obj

    def update(self: T, session: Session, **kwargs) -> T:
        kwargs['updated_at'] = datetime.utcnow()
        for key, value in kwargs.items():
            setattr(self, key, value)
        session.add(self)
        session.commit()
        session.refresh(self)
        return self

    def delete(self: T, session: Session) -> None:
        session.delete(self)
        session.commit()

    @classmethod
    def paginate(
        cls: type[T],
        session: Session,
        page: int = 1,
        per_page: int = 20
    ) -> Tuple[List[T], int]:
        statement = select(cls)
        total = session.exec(select(func.count()).select_from(statement)).one()

        offset = (page - 1) * per_page
        results = session.exec(
            statement.offset(offset).limit(per_page)
        ).all()

        return results, total</code>
로그인 후 복사
  1. 모델에 이 패턴을 사용하세요

기본 클래스를 정의한 후 이를 상속하는 모델을 만들 수 있습니다.

<code class="language-python">class Article(CRUDModel, table=True):
    title: str = Field(..., description="Article title")
    content: str = Field(..., description="Article content")
    status: str = Field(default="draft")

    # Relationships
    comments: List["Comment"] = Relationship(
        back_populates="article",
        sa_relationship_kwargs={"cascade": "all, delete-orphan"}
    )</code>
로그인 후 복사
  1. 모델 사용

이제 Python의 명시적인 세션 관리를 유지하면서 Rails와 유사한 구문을 사용하여 모델을 사용할 수 있습니다.

<code class="language-python">from db.session import get_session

# 列出所有文章
with get_session() as session:
    articles = Article.all(session)

# 查找特定文章
with get_session() as session:
    article = Article.find(session, "some-uuid")
    if article:
        print(f"Found: {article.title}")

# 创建新文章
with get_session() as session:
    article = Article.create(
        session,
        title="My New Article",
        content="Some content here"
    )

# 更新文章
with get_session() as session:
    article = Article.find(session, "some-uuid")
    if article:
        updated = article.update(
            session,
            title="Updated Title",
            content="New content"
        )

# 删除文章
with get_session() as session:
    article = Article.find(session, "some-uuid")
    if article:
        article.delete(session)

# 分页
with get_session() as session:
    articles, total = Article.paginate(session, page=2, per_page=10)</code>
로그인 후 복사

Rails와의 주요 차이점

이 패턴은 Python에 Rails와 같은 편리함을 제공하지만 주목해야 할 몇 가지 중요한 차이점이 있습니다.

  1. 명시적 세션 관리: Python에는 데이터베이스 트랜잭션을 더 잘 이해하는 데 도움이 되는 명시적 세션 관리가 필요합니다.
<code class="language-python"># 使用SQLModel的Python
with get_session() as session:
    article = Article.create(session, title="Hello")

# 与Rails对比
article = Article.create(title: "Hello")</code>
로그인 후 복사
  1. 유형 안전성: Python의 유형 힌트는 더 나은 IDE 지원을 제공하고 오류를 더 일찍 포착합니다.
<code class="language-python">class Article(CRUDModel, table=True):
    title: str  # 类型安全!
    views: int = Field(default=0)</code>
로그인 후 복사
  1. 클래스 메서드: Python은 인스턴스가 필요하지 않은 작업을 처리하기 위해 명시적인 @classmethod 데코레이터를 사용합니다.
  2. 오류 처리: Python은 명시적인 예외 처리를 권장합니다.
<code class="language-python">with get_session() as session:
    try:
        article = Article.find(session, "non-existent")
        if article is None:
            raise HTTPException(status_code=404, detail="Article not found")
    except Exception as e:
        # 处理其他数据库错误
        raise HTTPException(status_code=500, detail=str(e))</code>
로그인 후 복사

모범 사례

Python에서 이 패턴을 사용할 때는 다음 모범 사례를 염두에 두세요.

  1. 항상 컨텍스트 관리자 사용 :
<code class="language-python">   # 正确的做法
   with get_session() as session:
       article = Article.create(session, title="Hello")

   # 不正确的方法
   session = get_session()
   article = Article.create(session, title="Hello")
   session.close()</code>
로그인 후 복사
  1. 유형 안전:
<code class="language-python">   # 使用正确的类型提示
   def get_article(id: str) -> Optional[Article]:
       with get_session() as session:
           return Article.find(session, id)</code>
로그인 후 복사
  1. 확인:
<code class="language-python">   class Article(CRUDModel, table=True):
       title: str = Field(..., min_length=1, max_length=100)
       status: str = Field(
           default="draft",
           validate_default=True,
           validator=lambda x: x in ["draft", "published"]
       )</code>
로그인 후 복사
  1. 관계 관리:
<code class="language-python">   class Article(CRUDModel, table=True):
       # 正确使用级联删除
       comments: List["Comment"] = Relationship(
           back_populates="article",
           sa_relationship_kwargs={"cascade": "all, delete-orphan"}
       )</code>
로그인 후 복사

결론

유형 안전성을 유지하고 Python 모범 사례를 따르면서 Active Record 패턴을 Python에서 효율적으로 구현할 수 있습니다. Rails보다 더 명시적인 세션 관리가 필요하지만 비슷한 편의성을 제공하는 동시에 개발자에게 데이터베이스 작업에 대한 더 많은 제어권을 제공합니다.

이 모드는 다음과 같은 경우에 특히 적합합니다.

  • Rails에서 Python으로 마이그레이션한 팀
  • 모델 중심의 데이터베이스 작업을 선호하는 항목
  • 유형 안전성과 명시적인 세션 관리가 중요한 애플리케이션

이것은 Python에서 데이터베이스 작업을 수행하는 한 가지 방법일 뿐이라는 점을 기억하세요. SQLModel 및 SQLAlchemy는 특정 사용 사례에 더 적합할 수 있는 리포지토리 또는 데이터 액세스 개체와 같은 다른 모드를 지원합니다.

리소스

  • SQLModel 문서
  • SQLModel을 사용하는 FastAPI
  • SQLAlchemy 문서
  • Python에서 힌트 입력

위 내용은 SQLModel을 사용하여 Python에서 활성 레코드 패턴을 구현합니다의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿