fastapi-augment 0.1.2__tar.gz → 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/PKG-INFO +96 -6
  2. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/README.md +95 -5
  3. fastapi_augment-0.1.3/VERSION +1 -0
  4. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/config/settings.py +17 -0
  5. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/sqlalchemy/__init__.py +12 -0
  6. fastapi_augment-0.1.3/src/fastapi_augment/db/sqlalchemy/query_parser.py +447 -0
  7. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/sqlalchemy/repository_base.py +29 -1
  8. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/sqlalchemy/session.py +27 -18
  9. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/factory.py +7 -7
  10. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/openapi.py +0 -13
  11. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment.egg-info/PKG-INFO +96 -6
  12. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment.egg-info/SOURCES.txt +2 -0
  13. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_db_repository.py +429 -412
  14. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_openapi.py +0 -31
  15. fastapi_augment-0.1.3/tests/test_query_parser.py +246 -0
  16. fastapi_augment-0.1.2/VERSION +0 -1
  17. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/pyproject.toml +0 -0
  18. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/setup.cfg +0 -0
  19. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/__init__.py +0 -0
  20. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/common/__init__.py +0 -0
  21. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/common/constants.py +0 -0
  22. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/common/exception_handlers.py +0 -0
  23. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/common/exceptions.py +0 -0
  24. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/common/utils/__init__.py +0 -0
  25. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/common/utils/paths.py +0 -0
  26. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/common/utils/strings.py +0 -0
  27. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/config/__init__.py +0 -0
  28. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/__init__.py +0 -0
  29. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/sqlalchemy/alembic/README +0 -0
  30. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/sqlalchemy/alembic/__init__.py +0 -0
  31. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/sqlalchemy/alembic/env.py +0 -0
  32. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/sqlalchemy/alembic/script.py.mako +0 -0
  33. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/sqlalchemy/base.py +0 -0
  34. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/sqlalchemy/engine.py +0 -0
  35. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/sqlalchemy/migrate.py +0 -0
  36. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/sqlalchemy/mixins/__init__.py +0 -0
  37. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/sqlalchemy/mixins/audit.py +0 -0
  38. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/sqlalchemy/mixins/soft_delete.py +0 -0
  39. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/sqlalchemy/mixins/timestamp.py +0 -0
  40. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/db/sqlalchemy/model_base.py +0 -0
  41. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/health/__init__.py +0 -0
  42. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/health/checker.py +0 -0
  43. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/health/checkers.py +0 -0
  44. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/health/router.py +0 -0
  45. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/lifespan.py +0 -0
  46. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/log/__init__.py +0 -0
  47. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/log/config.py +0 -0
  48. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/log/factory.py +0 -0
  49. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/log/filters.py +0 -0
  50. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/log/handlers.py +0 -0
  51. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/middlewares/__init__.py +0 -0
  52. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/middlewares/base.py +0 -0
  53. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/middlewares/request_id.py +0 -0
  54. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/py.typed +0 -0
  55. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/schemas/__init__.py +0 -0
  56. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/schemas/base.py +0 -0
  57. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/schemas/pagination.py +0 -0
  58. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/schemas/request.py +0 -0
  59. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/schemas/response.py +0 -0
  60. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment/schemas/types.py +0 -0
  61. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment.egg-info/dependency_links.txt +0 -0
  62. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment.egg-info/entry_points.txt +0 -0
  63. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment.egg-info/requires.txt +0 -0
  64. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/src/fastapi_augment.egg-info/top_level.txt +0 -0
  65. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_config.py +0 -0
  66. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_constants.py +0 -0
  67. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_db_engine.py +0 -0
  68. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_db_session_models.py +0 -0
  69. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_exception_handlers.py +0 -0
  70. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_exceptions.py +0 -0
  71. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_factory.py +0 -0
  72. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_health.py +0 -0
  73. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_lifespan.py +0 -0
  74. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_log.py +0 -0
  75. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_middlewares.py +0 -0
  76. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_migrate.py +0 -0
  77. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_model_base.py +0 -0
  78. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_schemas.py +0 -0
  79. {fastapi_augment-0.1.2 → fastapi_augment-0.1.3}/tests/test_settings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-augment
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: FastAPI 通用代码工具包,跨项目复用
5
5
  Author-email: zarkhan <hanguangzheng@qq.com>
6
6
  License-Expression: MIT
@@ -45,10 +45,11 @@ Requires-Dist: fastapi-augment[config,orjson,sqlalchemy,uvicorn]; extra == "stan
45
45
  - **生命周期管理** — 多注册表、优先级、超时控制、异常策略的启动/关闭钩子
46
46
  - **读写分离** — 单库 / 主从 / 集群拓扑的异步引擎管理,线程安全的 Session 自动路由
47
47
  - **泛型仓储** — 类型安全的异步 Repository,支持直接实例化与子类继承两种方式
48
+ - **查询解析器** — REST 风格 query string 转 SQLAlchemy 表达式,支持 FIQL 条件、关键字搜索、排序
48
49
  - **可组合 Mixin** — 时间戳、审计、软删除等列混入,自由组合
49
50
  - **统一响应** — 全局 `APIResponse` 格式,自动追踪 `request_id`
50
51
  - **HTTP 异常** — 完整的 4xx 异常子类,内置默认文案
51
- - **OpenAPI 优化** — 自动清理 422 响应、可选 Bearer 认证
52
+ - **OpenAPI 优化** — 自动清理 422 响应与验证错误模型
52
53
  - **日志管理** — request_id 自动注入、uvicorn 接管、多进程安全轮转、幂等初始化、一键配置
53
54
  - **健康检查** — 可扩展的检查器模式,内置应用状态与数据库连通性检查,一行开关
54
55
  - **配置管理** — 基于 pydantic-settings,支持 `.env` 文件、环境变量前缀、嵌套配置
@@ -130,7 +131,7 @@ app = create_app(
130
131
  | 生命周期 | 接入 `fastapi_lifespan`,合并用户注册表与 `core_registry` |
131
132
  | 中间件 | 自动添加 `RequestIdMiddleware`,可选 CORS |
132
133
  | 路由 | 支持 `APIRouter` 列表或 `(router, kwargs)` 元组 |
133
- | OpenAPI | 自动清理 422 响应、可选 Bearer 认证 |
134
+ | OpenAPI | 自动清理 422 响应与验证错误模型 |
134
135
  | 数据库 | 可选挂载 `EngineManager` / `SessionFactory` 到 `app.state` |
135
136
  | 健康检查 | `health_check=True` 一键启用 `/health` 端点 |
136
137
 
@@ -147,7 +148,6 @@ app = create_app(
147
148
  title='My Service',
148
149
  registries=registry, # 单个或列表均可
149
150
  cors_allow_origins=['*'],
150
- openapi_enable_bearer_auth=True,
151
151
  health_check=True, # 启用健康检查
152
152
  )
153
153
  ```
@@ -260,10 +260,12 @@ from fastapi_augment.db.sqlalchemy import RepositoryBase
260
260
  # 方式 1:直接实例化 — 显式传入模型类
261
261
  user_repo = RepositoryBase(User)
262
262
 
263
+
263
264
  # 方式 2:子类继承 — 通过泛型参数绑定模型,可扩展自定义方法
264
265
  class UserRepo(RepositoryBase[User]):
265
266
  async def find_by_email(self, session, email: str) -> User | None:
266
- return await self.get_one(session, email=email)
267
+ return await self.get_first(session, email=email)
268
+
267
269
 
268
270
  user_repo = UserRepo() # 无需再传 User
269
271
  ```
@@ -279,7 +281,8 @@ async with sessions.transaction() as session:
279
281
  # Read(实例方法)
280
282
  async with sessions.read_session() as session:
281
283
  user = await user_repo.get(session, id_='01HXK...')
282
- user = await user_repo.get_one(session, name='alice')
284
+ user = await user_repo.get_first(session, name='alice') # 取第一条,无匹配返回 None
285
+ user = await user_repo.get_unique(session, email='a@b.com') # 精确唯一,多条匹配抛 MultipleResultsFound
283
286
  users = await user_repo.list(session, role='admin', order_by=['-created_at'], limit=10)
284
287
  total = await user_repo.count(session, is_active=True)
285
288
  has_admin = await user_repo.exists(session, role='admin')
@@ -319,6 +322,92 @@ await user_repo.list(session, expressions=(User.age > 18,))
319
322
  await user_repo.list(session, order_by=['-created_at', 'name'])
320
323
  ```
321
324
 
325
+ ### 查询解析器 — `query_parser`
326
+
327
+ 将 REST 风格的 query string 转为 SQLAlchemy `ColumnElement` 条件表达式,可直接传入 `RepositoryBase` 的 `expressions` / `order_by` 参数。
328
+
329
+ #### where 组合条件(FIQL 风格)
330
+
331
+ ```
332
+ where = and_group ("," and_group)* , 表示 OR
333
+ and_group = unit (";" unit)* ; 表示 AND
334
+ unit = "(" where ")" | condition
335
+ condition = field OP value
336
+ ```
337
+
338
+ **支持的操作符:**
339
+
340
+ | 语法 | 含义 | 示例 |
341
+ | ---------------- | -------------------- | ------------------------- |
342
+ | `field==value` | 等于 | `status==1` |
343
+ | `field!=value` | 不等 | `status!=0` |
344
+ | `field~=value` | 模糊包含 (ILIKE) | `name~=张` |
345
+ | `field>value` | 大于 | `age>18` |
346
+ | `field>=value` | 大于等于 | `age>=18` |
347
+ | `field<value` | 小于 | `age<60` |
348
+ | `field<=value` | 小于等于 | `age<=60` |
349
+ | `field~start~end`| 区间 (BETWEEN) | `age~18~60` |
350
+
351
+ ```python
352
+ from fastapi_augment.db.sqlalchemy import parse_where
353
+
354
+ # 昵称含张 且 状态非禁用
355
+ expr = parse_where('nickname~=张;status!=0', User)
356
+
357
+ # 括号内 OR,与区间 AND
358
+ expr = parse_where('(nickname~=张,username~=王);age~20~30', User)
359
+ ```
360
+
361
+ #### lookup 精确匹配
362
+
363
+ ```python
364
+ from fastapi_augment.db.sqlalchemy import parse_lookup
365
+
366
+ # 单字段精确匹配
367
+ expr = parse_lookup('phone==13800138000', User, fields={'phone', 'email'})
368
+
369
+ # 多字段 AND(; 分隔)
370
+ expr = parse_lookup('phone==138;status==1', User, fields={'phone', 'status'})
371
+ ```
372
+
373
+ #### 关键字搜索
374
+
375
+ ```python
376
+ from fastapi_augment.db.sqlalchemy import parse_keyword
377
+
378
+ # 多字段 OR 模糊搜索
379
+ expr = parse_keyword('admin', 'username,email,nickname', User)
380
+ ```
381
+
382
+ #### 排序
383
+
384
+ ```python
385
+ from fastapi_augment.db.sqlalchemy import parse_sort
386
+
387
+ # - 前缀表示降序,无前缀为升序
388
+ order_by = parse_sort('-created_at,nickname', User)
389
+ ```
390
+
391
+ #### 一键组合 — `build_query_expressions`
392
+
393
+ ```python
394
+ from fastapi_augment.db.sqlalchemy import build_query_expressions
395
+
396
+ expressions, order_by = build_query_expressions(
397
+ User,
398
+ where='status!=0;age>=18',
399
+ q='admin',
400
+ q_field='username,nickname',
401
+ sort='-created_at',
402
+ )
403
+
404
+ # 直接传给 paginate / list
405
+ result = await user_repo.paginate(
406
+ session, page=1, size=10,
407
+ expressions=expressions, order_by=order_by,
408
+ )
409
+ ```
410
+
322
411
  ### 数据库迁移 CLI — `fastapi-augment-migrate`
323
412
 
324
413
  内置 Alembic 迁移工具,提供 `init` / `generate` / `upgrade` 三个子命令,开箱即用。
@@ -654,6 +743,7 @@ fastapi_augment/
654
743
  │ ├── session.py # SessionFactory(读写分离)
655
744
  │ ├── model_base.py # ModelBase(ULID 主键)
656
745
  │ ├── repository_base.py # RepositoryBase(泛型仓储 + paginate)
746
+ │ ├── query_parser.py # 查询解析器(where / lookup / keyword / sort)
657
747
  │ ├── migrate.py # 数据库迁移 CLI
658
748
  │ ├── migrations/ # Alembic 迁移环境(env.py / script.py.mako)
659
749
  │ └── mixins/ # Timestamp / Audit / SoftDelete
@@ -8,10 +8,11 @@
8
8
  - **生命周期管理** — 多注册表、优先级、超时控制、异常策略的启动/关闭钩子
9
9
  - **读写分离** — 单库 / 主从 / 集群拓扑的异步引擎管理,线程安全的 Session 自动路由
10
10
  - **泛型仓储** — 类型安全的异步 Repository,支持直接实例化与子类继承两种方式
11
+ - **查询解析器** — REST 风格 query string 转 SQLAlchemy 表达式,支持 FIQL 条件、关键字搜索、排序
11
12
  - **可组合 Mixin** — 时间戳、审计、软删除等列混入,自由组合
12
13
  - **统一响应** — 全局 `APIResponse` 格式,自动追踪 `request_id`
13
14
  - **HTTP 异常** — 完整的 4xx 异常子类,内置默认文案
14
- - **OpenAPI 优化** — 自动清理 422 响应、可选 Bearer 认证
15
+ - **OpenAPI 优化** — 自动清理 422 响应与验证错误模型
15
16
  - **日志管理** — request_id 自动注入、uvicorn 接管、多进程安全轮转、幂等初始化、一键配置
16
17
  - **健康检查** — 可扩展的检查器模式,内置应用状态与数据库连通性检查,一行开关
17
18
  - **配置管理** — 基于 pydantic-settings,支持 `.env` 文件、环境变量前缀、嵌套配置
@@ -93,7 +94,7 @@ app = create_app(
93
94
  | 生命周期 | 接入 `fastapi_lifespan`,合并用户注册表与 `core_registry` |
94
95
  | 中间件 | 自动添加 `RequestIdMiddleware`,可选 CORS |
95
96
  | 路由 | 支持 `APIRouter` 列表或 `(router, kwargs)` 元组 |
96
- | OpenAPI | 自动清理 422 响应、可选 Bearer 认证 |
97
+ | OpenAPI | 自动清理 422 响应与验证错误模型 |
97
98
  | 数据库 | 可选挂载 `EngineManager` / `SessionFactory` 到 `app.state` |
98
99
  | 健康检查 | `health_check=True` 一键启用 `/health` 端点 |
99
100
 
@@ -110,7 +111,6 @@ app = create_app(
110
111
  title='My Service',
111
112
  registries=registry, # 单个或列表均可
112
113
  cors_allow_origins=['*'],
113
- openapi_enable_bearer_auth=True,
114
114
  health_check=True, # 启用健康检查
115
115
  )
116
116
  ```
@@ -223,10 +223,12 @@ from fastapi_augment.db.sqlalchemy import RepositoryBase
223
223
  # 方式 1:直接实例化 — 显式传入模型类
224
224
  user_repo = RepositoryBase(User)
225
225
 
226
+
226
227
  # 方式 2:子类继承 — 通过泛型参数绑定模型,可扩展自定义方法
227
228
  class UserRepo(RepositoryBase[User]):
228
229
  async def find_by_email(self, session, email: str) -> User | None:
229
- return await self.get_one(session, email=email)
230
+ return await self.get_first(session, email=email)
231
+
230
232
 
231
233
  user_repo = UserRepo() # 无需再传 User
232
234
  ```
@@ -242,7 +244,8 @@ async with sessions.transaction() as session:
242
244
  # Read(实例方法)
243
245
  async with sessions.read_session() as session:
244
246
  user = await user_repo.get(session, id_='01HXK...')
245
- user = await user_repo.get_one(session, name='alice')
247
+ user = await user_repo.get_first(session, name='alice') # 取第一条,无匹配返回 None
248
+ user = await user_repo.get_unique(session, email='a@b.com') # 精确唯一,多条匹配抛 MultipleResultsFound
246
249
  users = await user_repo.list(session, role='admin', order_by=['-created_at'], limit=10)
247
250
  total = await user_repo.count(session, is_active=True)
248
251
  has_admin = await user_repo.exists(session, role='admin')
@@ -282,6 +285,92 @@ await user_repo.list(session, expressions=(User.age > 18,))
282
285
  await user_repo.list(session, order_by=['-created_at', 'name'])
283
286
  ```
284
287
 
288
+ ### 查询解析器 — `query_parser`
289
+
290
+ 将 REST 风格的 query string 转为 SQLAlchemy `ColumnElement` 条件表达式,可直接传入 `RepositoryBase` 的 `expressions` / `order_by` 参数。
291
+
292
+ #### where 组合条件(FIQL 风格)
293
+
294
+ ```
295
+ where = and_group ("," and_group)* , 表示 OR
296
+ and_group = unit (";" unit)* ; 表示 AND
297
+ unit = "(" where ")" | condition
298
+ condition = field OP value
299
+ ```
300
+
301
+ **支持的操作符:**
302
+
303
+ | 语法 | 含义 | 示例 |
304
+ | ---------------- | -------------------- | ------------------------- |
305
+ | `field==value` | 等于 | `status==1` |
306
+ | `field!=value` | 不等 | `status!=0` |
307
+ | `field~=value` | 模糊包含 (ILIKE) | `name~=张` |
308
+ | `field>value` | 大于 | `age>18` |
309
+ | `field>=value` | 大于等于 | `age>=18` |
310
+ | `field<value` | 小于 | `age<60` |
311
+ | `field<=value` | 小于等于 | `age<=60` |
312
+ | `field~start~end`| 区间 (BETWEEN) | `age~18~60` |
313
+
314
+ ```python
315
+ from fastapi_augment.db.sqlalchemy import parse_where
316
+
317
+ # 昵称含张 且 状态非禁用
318
+ expr = parse_where('nickname~=张;status!=0', User)
319
+
320
+ # 括号内 OR,与区间 AND
321
+ expr = parse_where('(nickname~=张,username~=王);age~20~30', User)
322
+ ```
323
+
324
+ #### lookup 精确匹配
325
+
326
+ ```python
327
+ from fastapi_augment.db.sqlalchemy import parse_lookup
328
+
329
+ # 单字段精确匹配
330
+ expr = parse_lookup('phone==13800138000', User, fields={'phone', 'email'})
331
+
332
+ # 多字段 AND(; 分隔)
333
+ expr = parse_lookup('phone==138;status==1', User, fields={'phone', 'status'})
334
+ ```
335
+
336
+ #### 关键字搜索
337
+
338
+ ```python
339
+ from fastapi_augment.db.sqlalchemy import parse_keyword
340
+
341
+ # 多字段 OR 模糊搜索
342
+ expr = parse_keyword('admin', 'username,email,nickname', User)
343
+ ```
344
+
345
+ #### 排序
346
+
347
+ ```python
348
+ from fastapi_augment.db.sqlalchemy import parse_sort
349
+
350
+ # - 前缀表示降序,无前缀为升序
351
+ order_by = parse_sort('-created_at,nickname', User)
352
+ ```
353
+
354
+ #### 一键组合 — `build_query_expressions`
355
+
356
+ ```python
357
+ from fastapi_augment.db.sqlalchemy import build_query_expressions
358
+
359
+ expressions, order_by = build_query_expressions(
360
+ User,
361
+ where='status!=0;age>=18',
362
+ q='admin',
363
+ q_field='username,nickname',
364
+ sort='-created_at',
365
+ )
366
+
367
+ # 直接传给 paginate / list
368
+ result = await user_repo.paginate(
369
+ session, page=1, size=10,
370
+ expressions=expressions, order_by=order_by,
371
+ )
372
+ ```
373
+
285
374
  ### 数据库迁移 CLI — `fastapi-augment-migrate`
286
375
 
287
376
  内置 Alembic 迁移工具,提供 `init` / `generate` / `upgrade` 三个子命令,开箱即用。
@@ -617,6 +706,7 @@ fastapi_augment/
617
706
  │ ├── session.py # SessionFactory(读写分离)
618
707
  │ ├── model_base.py # ModelBase(ULID 主键)
619
708
  │ ├── repository_base.py # RepositoryBase(泛型仓储 + paginate)
709
+ │ ├── query_parser.py # 查询解析器(where / lookup / keyword / sort)
620
710
  │ ├── migrate.py # 数据库迁移 CLI
621
711
  │ ├── migrations/ # Alembic 迁移环境(env.py / script.py.mako)
622
712
  │ └── mixins/ # Timestamp / Audit / SoftDelete
@@ -0,0 +1 @@
1
+ 0.1.3
@@ -52,6 +52,23 @@ class EnvSettings(BaseSettings):
52
52
  extra='ignore',
53
53
  )
54
54
 
55
+ # ------------------------------
56
+ # 项目信息
57
+ # ------------------------------
58
+ project_debug: bool = True
59
+ project_title: str = 'FastAPI Augment'
60
+ project_summary: str = 'FastAPI Augment - Extended utilities and patterns for FastAPI'
61
+ project_description: str = (
62
+ 'FastAPI Augment is a lightweight extension library for FastAPI that '
63
+ 'provides out-of-the-box solutions for common backend challenges. It '
64
+ 'includes asynchronous database session management (with read-write splitting), '
65
+ 'unified API response models, pagination helpers, and streamlined dependency '
66
+ 'injection for transactional operations. Designed to reduce boilerplate and '
67
+ 'enforce clean architecture, it accelerates the development of production-ready '
68
+ 'web services.'
69
+ )
70
+ project_version: str = '0.1.0'
71
+
55
72
  @classmethod
56
73
  def from_env(cls: type[_S], **kwargs: Any) -> _S:
57
74
  """从环境加载配置,支持 ``SettingsConfigDict`` 所有参数。
@@ -6,6 +6,13 @@
6
6
  from .base import Base
7
7
  from .engine import NodeConfig, ClusterTopology, EngineManager
8
8
  from .model_base import ModelBase
9
+ from .query_parser import (
10
+ parse_lookup,
11
+ parse_where,
12
+ parse_keyword,
13
+ parse_sort,
14
+ build_query_expressions
15
+ )
9
16
  from .repository_base import RepositoryBase
10
17
  from .session import SessionFactory
11
18
 
@@ -15,6 +22,11 @@ __all__ = [
15
22
  'ClusterTopology',
16
23
  'EngineManager',
17
24
  'ModelBase',
25
+ 'parse_lookup',
26
+ 'parse_where',
27
+ 'parse_keyword',
28
+ 'parse_sort',
29
+ 'build_query_expressions',
18
30
  'RepositoryBase',
19
31
  'SessionFactory'
20
32
  ]