Pembangun Python sering terlepas interaksi pangkalan data elegan Active Record apabila berhijrah daripada Ruby on Rails ke Python. Walaupun SQLAlchemy Python (dan oleh itu SQLModel) menggunakan pendekatan yang berbeza secara lalai, kami boleh melaksanakan corak yang sama untuk membawa kemudahan model gaya Rails kepada aplikasi Python sambil mengekalkan keselamatan jenis dan mengikuti amalan terbaik Python.
Mod Rakaman Aktif
Corak Rekod Aktif (dipopularkan oleh Ruby on Rails) menganggap rekod pangkalan data sebagai objek dengan kaedah manipulasi pangkalan data. Tidak perlu menggunakan kelas repositori yang berasingan atau objek akses data (DAO), model itu sendiri tahu cara berinteraksi dengan pangkalan data.
Sebagai contoh, dalam Rails anda boleh menulis:
<code class="language-ruby"># 查找记录 user = User.find(123) # 更新记录 user.name = "New Name" user.save # 创建新记录 post = Post.create(title: "Hello World")</code>
Menggunakan SQLModel dalam Python
Walaupun SQLModel Python tidak menyediakan mod ini secara langsung, kami boleh melaksanakannya menggunakan kelas asas yang menyediakan operasi biasa ini. Begini caranya:
Pertama, kami mencipta kelas asas yang melaksanakan operasi CRUD biasa:
<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>
Selepas menentukan kelas asas, kita boleh mencipta model yang mewarisinya:
<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>
Kini kami boleh menggunakan sintaks seperti Rails untuk menggunakan model kami sambil mengekalkan pengurusan sesi eksplisit Python:
<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>
Perbezaan utama dengan Rails
Walaupun corak ini membawa kemudahan seperti Rails kepada Python, terdapat beberapa perbezaan penting yang perlu diperhatikan:
<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
eksplisit untuk mengendalikan operasi yang tidak memerlukan contoh. <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>
Amalan Terbaik
Apabila menggunakan corak ini dalam Python, ingatlah amalan terbaik berikut:
<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>
Kesimpulan
Corak Rekod Aktif boleh dilaksanakan dengan cekap dalam Python sambil mengekalkan keselamatan jenis dan mengikuti amalan terbaik Python. Walaupun ia memerlukan pengurusan sesi yang lebih jelas daripada Rails, ia menawarkan kemudahan yang sama sambil memberikan pembangun lebih kawalan ke atas operasi pangkalan data.
Mod ini amat sesuai untuk:
ingat, ini hanya satu kaedah operasi pangkalan data dalam Python. SQLModel dan SQLalChemy menyokong mod lain, seperti objek repositori atau data akses, yang mungkin lebih sesuai untuk kes -kes tertentu.
Sumber
Atas ialah kandungan terperinci Melaksanakan Corak Rekod Aktif dalam Python dengan SQLModel. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!