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은 이 모드를 직접 제공하지 않지만 이러한 공통 작업을 제공하는 기본 클래스를 사용하여 구현할 수 있습니다. 방법은 다음과 같습니다.
먼저 일반적인 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>
기본 클래스를 정의한 후 이를 상속하는 모델을 만들 수 있습니다.
<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>
이제 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와 같은 편리함을 제공하지만 주목해야 할 몇 가지 중요한 차이점이 있습니다.
<code class="language-python"># 使用SQLModel的Python with get_session() as session: article = Article.create(session, title="Hello") # 与Rails对比 article = Article.create(title: "Hello")</code>
<code class="language-python">class Article(CRUDModel, table=True): title: str # 类型安全! views: int = Field(default=0)</code>
@classmethod
데코레이터를 사용합니다. <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에서 이 패턴을 사용할 때는 다음 모범 사례를 염두에 두세요.
<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>
<code class="language-python"> # 使用正确的类型提示 def get_article(id: str) -> Optional[Article]: with get_session() as session: return Article.find(session, id)</code>
<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>
<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보다 더 명시적인 세션 관리가 필요하지만 비슷한 편의성을 제공하는 동시에 개발자에게 데이터베이스 작업에 대한 더 많은 제어권을 제공합니다.
이 모드는 다음과 같은 경우에 특히 적합합니다.
이것은 Python에서 데이터베이스 작업을 수행하는 한 가지 방법일 뿐이라는 점을 기억하세요. SQLModel 및 SQLAlchemy는 특정 사용 사례에 더 적합할 수 있는 리포지토리 또는 데이터 액세스 개체와 같은 다른 모드를 지원합니다.
리소스
위 내용은 SQLModel을 사용하여 Python에서 활성 레코드 패턴을 구현합니다의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!