Skip to main content

pyre-sqlalchemy-db

Python SQLAlchemy 2.0 License Async

基于 SQLAlchemy 2.0 的轻量 ORM 增强库:声明式字段、事务管理、分页、软删除、雪花 ID 以及完整的异步支持,并与 Flask / Starlette 等框架无侵入集成。

✨ 特点

  • 🧱 声明式字段 — StringField、DateTimeField、ForeignKeyField 开箱即用,参数透传 mapped_column。
  • 🔁 事务管理 — transactional / local_transaction,支持 REQUIRED / NEW / MANDATORY 传播与隔离级别。
  • ⚡ 异步支持 — async_transactional / Model.async_query,同一套模型同步、异步通用。
  • 🧩 常用 Mixin — 主键、创建/更新时间、软删除、操作人,按需组合。
  • 🆔 主键策略 — 自增、雪花 ID、UUID 三种,一行切换。
  • 🔌 多数据源 — 按 schema 绑定多个引擎,模型自动路由。
  • 📤 序列化 — to_dict() 内置循环引用保护与日期 / Decimal / 枚举编码。
  • 🪶 框架无关 — 核心不依赖任何 Web 框架,可选接入 Flask 应用上下文。

📦 安装

pip install pyre-sqlalchemy-db

按需安装可选依赖:

pip install "pyre-sqlalchemy-db[async]"   # greenlet / aiosqlite / aiomysql / asyncpg
pip install "pyre-sqlalchemy-db[mysql]"
pip install "pyre-sqlalchemy-db[flask]"

💡 一个简单的例子

from sqlalchemy_db import SQLAlchemyDB, models

db = SQLAlchemyDB("sqlite:///demo.db")


class User(models.PkMixin, models.TimestampMixin, models.Model):
    __tablename__ = "user"

    name = models.StringField(50, comment="用户名")
    age = models.IntegerField(default=0)

字段、模型与 Mixin 统一从 models 命名空间取用(models 即 sqlalchemy_db.models 子包)。

👩‍💻 目录结构

sqlalchemy-db
├── sqlalchemy_db
│   ├── __init__.py           # 对外导出
│   ├── app.py                # 框架集成入口
│   ├── transaction.py        # 同步事务
│   ├── async_transaction.py  # 异步事务
│   ├── snowflake.py          # 雪花 ID 生成
│   ├── encoders.py           # 序列化编码器
│   ├── exceptions.py         # 异常体系
│   ├── models/               # Model / 字段 / Mixin / 查询
│   ├── globals.py            # 实例解析
│   ├── constants.py
│   └── utils.py
├── examples/                 # 可运行示例
├── tests/                    # 单元测试
└── setup.py

🚀 快速开始

from sqlalchemy_db import SQLAlchemyDB, Page, local_transaction

db = SQLAlchemyDB("sqlite:///demo.db")
db.create_all()

# 写入
with local_transaction():
    user = User(name="Alice", age=18)
    user.insert()
    print(user.id)          # 1

# 更新与删除
with local_transaction():
    user.save()
    user.delete()

# 查询与分页
with local_transaction():
    User.query.get_by_id_or_404(1)
    User.query.select(User.age >= 18, order_by=User.id.desc())

    page = Page(page=1, page_size=20)
    User.query.select_page(page)
    page.get_data()             # 数据列表
    page.get_count()            # 总条数

Model.query 在访问时即从当前会话上下文取 Session,因此所有查询都要运行在 local_transaction() / transactional 上下文内。否则库会告警事务上下文不会自动回收。

🧱 模型

字段

字段 对应类型
StringField(255) String
TextField() / MediumtextField() Text / MEDIUMTEXT
IntegerField / BigIntegerField / SmallIntegerField 整型
FloatField / NumericField / DecimalField 浮点 / 精确数值
BooleanField() Boolean
DateField / DateTimeField / TimeField 日期时间
JSONField() JSON
BinaryField() LargeBinary
EnumField / IntEnumField / StrEnumField 枚举
ForeignKeyField("user.id") 外键
AutoPkField(pk_type=...) 主键(AUTO / SNOWFLAKE / UUID)

所有字段均透传 mapped_column 参数,nullable、comment、server_default、index、 unique、sort_order 照常可用。

Mixin

Mixin 说明
PkMixin 提供 id 主键
TimestampMixin 自动维护 create_time / update_time
SoftDeleteMixin 提供 delete_time 列与软删除查询支持
Model 基础模型,内置实例级 insert / save / delete

主键策略

from sqlalchemy_db import PkType, models


class Order(models.Model):
    __tablename__ = "order"
    id = models.AutoPkField(pk_type=PkType.SNOWFLAKE)

序列化

user.to_dict()
user.to_dict(exclude={"age"}, exclude_none=True)

User.from_dict({"name": "Bob", "age": 20})
User.from_entity(pydantic_model)

🔍 查询

Model.query / Model.async_query 提供统一的链式查询入口。查询须在会话上下文内执行:

with local_transaction():
    User.query.get_by_id(1)                       # 按主键
    User.query.get_by_id_or_404(1)                # 不存在抛 NotFoundDataException
    User.query.get_one(User.name == "Alice")
    User.query.select(User.age >= 18, order_by=User.id.desc())
    User.query.select_batch_ids([1, 2, 3])
    User.query.select_count(User.is_active.is_(True))
    User.query.delete_by_id_or_404(1)

软删除:

with local_transaction():
    User.query.with_not_trashed().all()   # 排除已删除
    User.query.only_trashed().all()       # 仅已删除
    User.query.with_trashed().all()       # 全部

🔁 事务

from sqlalchemy_db import transactional, local_transaction, Propagation, Isolation


@transactional
def create_user(name: str):
    User(name=name).insert()


with local_transaction():
    User(name="Bob").insert()


@transactional(propagation=Propagation.NEW, isolation=Isolation.READ_COMMITTED, autocommit=True)
def task():
    ...

⚡ 异步

模型无需改动,异步场景使用 async_transactional 与 Model.async_query:

from sqlalchemy_db import SQLAlchemyDB, async_transactional

db = SQLAlchemyDB("sqlite+aiosqlite:///demo.db")


@async_transactional
async def main():
    user = await User.async_query.get_by_id(1)
    rows = await User.async_query.select(User.age >= 18)
    page = await User.async_query.select_page(Page(page=1, page_size=20))

⚙️ 配置

db = SQLAlchemyDB({
    "SQLALCHEMY_DATABASE_URI": "mysql+pymysql://root:123456@127.0.0.1:3306/demo",
    "SQLALCHEMY_ECHO": False,
    "SQLALCHEMY_ENGINE_OPTIONS": {"pool_size": 10, "pool_recycle": 3600},
    "SQLALCHEMY_ASYNC_MODE": "auto",          # auto / sync / async
    "SNOWFLAKE_DATACENTER_ID": 1,
    "SNOWFLAKE_WORKER_ID": 1,
})
配置项 说明
SQLALCHEMY_DATABASE_URI 主库连接串
SQLALCHEMY_ENGINE_OPTIONS 引擎参数
SQLALCHEMY_SESSION_OPTIONS Session 参数
SQLALCHEMY_ECHO 打印 SQL
SQLALCHEMY_ASYNC_MODE auto / sync / async
SQLALCHEMY_SCHEMAS 多数据源,{schema: url}
SNOWFLAKE_DATACENTER_ID / SNOWFLAKE_WORKER_ID / SNOWFLAKE_EPOCH 雪花 ID 配置

🔌 多数据源

from sqlalchemy_db import models


class Log(models.Model):
    __tablename__ = "log"
    __schema__ = "log"        # 路由到 "log" 数据源
db = SQLAlchemyDB({
    "SQLALCHEMY_DATABASE_URI": "mysql+pymysql://.../main",
    "SQLALCHEMY_SCHEMAS": {"log": "mysql+pymysql://.../logs"},
})

🧩 Flask 集成

from flask import Flask
from sqlalchemy_db import SQLAlchemyDB

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@127.0.0.1:3306/demo"

db = SQLAlchemyDB(app)


@app.route("/users/<int:uid>")
def get_user(uid):
    return db.session.get(User, uid).to_dict()

位于 Flask 应用上下文内时,Model.query 等入口会自动解析当前应用绑定的实例。

📚 示例

更多可运行示例见 examples/。

📄 许可

本项目基于 MIT 许可开源。

Metadata

Release files for pyre-sqlalchemy-db 1.0.0

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

Source distribution (sdist)

Source distribution for pyre-sqlalchemy-db 1.0.0
File Size Uploaded Provenance
pyre_sqlalchemy_db-1.0.0.tar.gz 35.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pyre-sqlalchemy-db 1.0.0
File Interpreter ABI Platform
pyre_sqlalchemy_db-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 71.6 kB

Release files / pyre_sqlalchemy_db-1.0.0.tar.gz

Download URL pyre_sqlalchemy_db-1.0.0.tar.gz
Size 35.1 kB
Tags Source
SHA-256 checksum
How to use checksums
952c0234bbc19e0c2b855a83f2b4c4b93405f4a07c204366daf24059391e396f
BLAKE2b-256 checksum
How to use checksums
371799324d1098cd046b7a88e20fc557ca2d40076287f748ccf11ff3a7d7810a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / pyre_sqlalchemy_db-1.0.0-py3-none-any.whl

Download URL pyre_sqlalchemy_db-1.0.0-py3-none-any.whl
Size 36.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dd3348894218bc89d2f9bb34266280a09648f5a875f1312ccf0c11f8cfd15a20
BLAKE2b-256 checksum
How to use checksums
dfb06ee464cf814c2bf7881559b42e7eeb1a60a25d84e996db9aa42cd305ce8c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for pyre-sqlalchemy-db 1.0.0

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.

Release history Release notifications | RSS feed

This release

1.0.0 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