feat: add typed fluent query builders - #107
Conversation
Bring CRUDPlus closer to common ORM workflows with upsert_model, select_models_paginated, global soft-delete filtering, and field__op atomic expression updates. Co-authored-by: Cursor <cursoragent@cursor.com>
|
此方案正在评估中 |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
|
@wu-clan 你好评估意见如何。如有建议可以增加评论 |
|
感谢你的贡献和详细的设计说明,也感谢补充文档与测试。 经过评估,当前形态下我们不准备合并此 PR,原因如下。 1. 与项目定位不符sqlalchemy-crud-plus 的定位是:基于 SQLAlchemy 2.0 的异步 CRUD SDK,补齐常见增删改查、过滤与批量操作,复杂查询应回落 SQLAlchemy 原生 API 本 PR 引入了接近完整 ORM QuerySet 的链式构建器(投影、聚合、JOIN、CTE、Union、stream 等),维护面和心智模型都更接近「第二套查询层」,会显著改变库的边界与长期维护成本。这不是当前项目希望承担的方向 2. 范围过大,难以作为单一变更接受PR 同时包含多组正交能力:
即便其中部分能力(如分页、Upsert、原子更新)有产品价值,也不适合与完整链式 DSL 绑在同一 PR 中整包合入。在「是否引入 QueryBuilder」这一方向性决策为否的前提下,整包合并不合适 3. 类型化链式查询的收益与成本不匹配字符串
而不是在库内再实现一层近似 Django/Tortoise 的 QuerySet 再次感谢你的时间与用心。理解若与预期不同,欢迎继续围绕上述小范围能力参与讨论 |
背景
当前 CRUDPlus 主要通过关键字字符串构造过滤条件,例如
name__like、age__ge。这种方式虽然便于快速开发,但字段名无法获得 IDE 补全、重命名支持和静态类型检查,字段写错通常只能在运行时发现。本 PR 在保留现有 CRUD API 和字符串过滤兼容性的基础上,增加基于 SQLAlchemy 表达式的不可变链式查询构建器,并提供强类型 Lambda 写法。
主要变更
1. 新增链式查询 API
支持以下查询能力:
count、exists、first、one、scalarmax、min、sum、avgdistinct、group_by、havingfor_update和原生statement导出to_sqlSQL 预览示例:
2. 强类型字段表达式
Lambda 参数会根据
CRUDPlus[Model]推断为对应模型类型:不存在的模型字段可以由 IDE 和
ty报告,而不是等到 SQL 执行时才发现。JOIN 条件也支持双模型表达式:
3. 链式写入
新增独立写入构建器:
update_querydelete_queryinsert_queryupsert_query同时支持从查询链直接更新或删除:
写入构建器支持:
where和setreturningflush和commit4. 写入安全保护
链式 update/delete 没有显式过滤条件时默认抛出
UnsafeWriteError:如果确实需要全表操作,必须显式调用:
5. 软删除支持
启用
filter_deleted=True后,链式查询、更新和删除都会自动排除软删除记录;可以使用include_deleted()显式包含已删除记录。6. 文档和测试
1.14.0兼容性
create_model、select_models、update_model等 APIfield__operator字符串过滤语法验证结果
384 passedty check:通过备注
Python 不支持像 C# 一样重载
and/or生成 SQL 表达式,因此复杂逻辑使用 SQLAlchemy 的&、|,或使用where_or()、where_if()和or_if()。