Skip to main content

Fluent Alchemy

輕鬆流暢地使用 SQLAclhemy

Installation

pip insall fluent-alchemy

Quick start

  1. 宣告 Models 並繼承 ActiveRecord
# models.py
from sqlalchemy.orm import DeclarativeBase
from fluent_alchemy import ActiveRecord

class Base(DeclarativeBase, ActiveRecord):
    pass

class User(Base):
    __tablename__ = "users"

    id: Mapped[int] = mapped_column(BigInteger(), primary_key=True)
    email: Mapped[str] = mapped_column(String(), unique=True)
    password: Mapped[str] = mapped_column(String())
    name: Mapped[str] = mapped_column(String(50))
    state: Mapped[bool] = mapped_column(Boolean())
  1. 建立 SQLAclhemy Engine, 並指派給 ActiveRecord 內的 session handler
from sqlalchemy import create_engine
from models import Base

engine = create_engine("sqlite://:memory:", echo=True)

Base.set_engine(engine)
  1. 開始使用 model 操作 database !
from models import User

users = User.all()
  1. 使用完畢後,釋放 Session 資源
from models import Base

Base.remove_scoped_session()

Features

Active Record

利用 QueryBuilder 來處理 SQLAlchemy 的 select() query statement

  • Create

    from models import User
    
    user = User.create(
        name="Justin",
        email="corey97@example.org",
        password="NioWe9Wn#+"
    )
    
    # or
    
    user = User(
        name="Justin",
        email="corey97@example.org",
        password="NioWe9Wn#+"
    )
    user.save()
    
  • Read

    1. Find by id

      user = User.find(1)
      
    2. 只回傳特定欄位

      user = User.select(User.id, User.name, User.email).first()
      
    3. 透過 where 增加查詢條件

      user = User.where(User.email == "corey97@example.org").first()
      
      users = User.where(User.state.is_(True)).get()
      
  • Update

    user = User.find(1)
    user.passwod = "6xjVAY$p&D"
    
    user.save()
    
  • Delete

    user = User.find(1)
    user.delete()
    
  • Pagenate

    # setting page number and rows count per page
    pagination = User.paginate(page=1, per_page=15)
    
    """
    {
        "total": 100,
        "per_page": 15,
        "current_page": 1,
        "last_page": 7,
        "data": [ ... ], # ussers
    }
    """
    

Mixins

TimestampMixin

讓指定的 Model class 繼承 TimestampMixin,讓該 Model 補上 created_at, updated_at 欄位。

from fluent_alchemy import ActiveRecord, TimestampMixin

class Base(DeclarativeBase, ActiveRecord):
    pass

class User(Base, TimestampMixin):
    __tablename__ = "users"
    ...

###
user = User.find(1)

print(user.created_at)
print(user.updated_at)

SoftDeleteMixin

讓指定的 Model class 繼承 SoftDeleteMixin,就可以讓該 Model 擁有 Soft delete 的能力。

from sqlalchemy.orm import DeclarativeBase
from fluent_alchemy import ActiveRecord, SoftDeleteMixin

class Base(DeclarativeBase, ActiveRecord):
    pass

class User(Base, SoftDeleteMixin):
    __tablename__ = "users"

    id: Mapped[int] = mapped_column(BigInteger(), primary_key=True)
    email: Mapped[str] = mapped_column(String(), unique=True)
    password: Mapped[str] = mapped_column(String())
    name: Mapped[str] = mapped_column(String(50))
    state: Mapped[bool] = mapped_column(Boolean())

SoftDeleteMixin 會自動補上 deleted_at 欄位,依此欄位來處理 soft delete 的資料。

deleted_at: Mapped[Optional[datetime]] = mapped_column(TIMESTAMP(), nullable=True)

設定完成後,之後對此 Model 進行 Query 時,會在 statement 內的 WHERE 條件自動加上 deleted_at IS NULL。

查詢已被標記刪除的資料

users_deleted = User.where(...).get(with_trashed=True)

強制刪除 (Force delete)

user = User.find(1)

user.delete(force=True)

Examples

在 FastAPI 內使用

from contextlib import asynccontextmanager
from fastapi import FastAPI, Depends
from app.models import BaseModel, User

def close_scoped_session():
    """
    Remove the scoped session at the enf of every request.
    """
    yield
    BaseModel.remove_scoped_session()

@asynccontextmanager
async def lifespan(app: FastAPI):
    """
    Set engine to the ScopedSessionHandler when FastAPI app started.
    """
    BaseModel.set_engine(engine)
    yield

app = FastAPI(
    title="MyApp",
    dependencies=[Depends(close_scoped_session)],
    lifespan=lifespan
)

@app.get("/users")
def index():
    return User.all()

Metadata

Release files for fluent-alchemy 0.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fluent-alchemy 0.0.2
File Size Uploaded Provenance Actions
fluent_alchemy-0.0.2.tar.gz 8.4 kB Without provenance Details for fluent_alchemy-0.0.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for fluent-alchemy 0.0.2
File Interpreter ABI Platform Actions
fluent_alchemy-0.0.2-py3-none-any.whl Python 3 none any Details for fluent_alchemy-0.0.2-py3-none-any.whl

Total release size: 18.8 kB

Release files / fluent_alchemy-0.0.2.tar.gz

Download URL fluent_alchemy-0.0.2.tar.gz
Size 8.4 kB
Tags Source
SHA-256 checksum
How to use checksums
9ffb786ef63d397c879675c3715a5c253a3ec549b14069585a7ca3fbfff029a9
BLAKE2b-256 checksum
How to use checksums
e7274bca5f51e6ccadbf686f02ce1814b52d2458548f366934c4ab61a755dd0e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.8.2 CPython/3.10.11 Darwin/23.2.0

Release files / fluent_alchemy-0.0.2-py3-none-any.whl

Download URL fluent_alchemy-0.0.2-py3-none-any.whl
Size 10.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a70d3e0ca14696a36a40b17c62a3e7d8157bceb273c71bae4a959833ad383ff0
BLAKE2b-256 checksum
How to use checksums
0bb8dd775f5300af462bdf4b18a8c352e3e6e654ee2142d6308c163fd6183a35
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.8.2 CPython/3.10.11 Darwin/23.2.0

Security for fluent-alchemy 0.0.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.0.2 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page