sdpy-kit 0.2.5__tar.gz → 0.2.6__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 (46) hide show
  1. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/PKG-INFO +10 -2
  2. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/README.md +9 -1
  3. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/__init__.py +1 -1
  4. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/db/base_db_kit.py +38 -11
  5. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/.gitignore +0 -0
  6. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/ai/__init__.py +0 -0
  7. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/ai/base_service.py +0 -0
  8. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/ai/chat_service.py +0 -0
  9. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/ai/embedding_service.py +0 -0
  10. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/ai/exceptions.py +0 -0
  11. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/ai/failover.py +0 -0
  12. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/ai/image_service.py +0 -0
  13. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/ai/model_builder.py +0 -0
  14. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/ai/model_client.py +0 -0
  15. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/ai/pool.py +0 -0
  16. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/ai/profiles.py +0 -0
  17. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/ai/rerank_service.py +0 -0
  18. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/ai/runner.py +0 -0
  19. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/ai/types.py +0 -0
  20. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/anydoc_kit.py +0 -0
  21. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/common_kit.py +0 -0
  22. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/config/__init__.py +0 -0
  23. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/config/kit_config.py +0 -0
  24. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/config/log_config.py +0 -0
  25. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/db/__init__.py +0 -0
  26. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/db/crud.py +0 -0
  27. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/db/engine.py +0 -0
  28. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/db/exceptions.py +0 -0
  29. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/db/models/__init__.py +0 -0
  30. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/db/models/base.py +0 -0
  31. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/db/mysql_kit.py +0 -0
  32. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/db/pg_kit.py +0 -0
  33. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/db/query.py +0 -0
  34. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/db/session.py +0 -0
  35. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/db/sqlite_kit.py +0 -0
  36. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/db/transaction.py +0 -0
  37. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/docx_kit.py +0 -0
  38. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/file_kit.py +0 -0
  39. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/marker_kit.py +0 -0
  40. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/mcp_kit.py +0 -0
  41. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/md2doc_kit.py +0 -0
  42. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/mineru_kit.py +0 -0
  43. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/redis_kit.py +0 -0
  44. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/wx_article_kit.py +0 -0
  45. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/kit/zvec_kit.py +0 -0
  46. {sdpy_kit-0.2.5 → sdpy_kit-0.2.6}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sdpy-kit
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: SDPY Kit——统一数据库访问层(PG/MySQL/SQLite)与 AI/MCP/Redis/文件/文档/向量工具集
5
5
  Author-email: Clark <changhongyuan@126.com>
6
6
  License-Expression: MIT
@@ -512,7 +512,15 @@ PgKit.search_vectors("my_vec", [0.1] * 384, top_k=5, id_col="vid", column="vec")
512
512
  > 新增(非破坏性):`VECTOR_CAPABILITIES` 能力声明、`id_col` / `column` 逃生口参数、
513
513
  > `insert_vectors` 支持二维 numpy 数组与批量提交。
514
514
 
515
- #### 0.2.5 变更(开发中,未发布)
515
+ #### 0.2.6 变更
516
+
517
+ | 编号 | 变更 | 影响 |
518
+ |------|------|------|
519
+ | D1 | `prepare_statement` 的 `params` 支持**参数行列表**(`list[dict]`):**原样返回该列表** → `session.execute(*prepare_statement(sql, params))` 即批量执行(executemany),与 `build_insert_vectors` 的返回形态直接对接;行键集不一致或行值含序列 → 本地可操作 `ValueError`(与 `execute` 批量形态**同一规则**) | 向后兼容:单字典 / `None` 形态行为不变;行列表形态**不做** `IN` 展开(与批量互斥) |
520
+ | D1 | 文档:修正「自有事务」示例——0.2.5 的示例把 `build_insert_vectors` 返回的**行列表**传给了单字典形态,照抄会抛 `AttributeError: 'list' object has no attribute 'items'` | **纯文档缺陷修正**(0.2.5 示例照抄即崩) |
521
+ | — | 文档:批量执行补充 `rowcount` 备注——忽略型写入(如 SQLite `INSERT OR IGNORE`)的冲突行不计入 `rowcount`(即 `rowcount` = 实际插入数;⚠ 仅 SQLite 实测) | 文档 |
522
+
523
+ #### 0.2.5 变更
516
524
 
517
525
  | 编号 | 变更 | 影响 |
518
526
  |------|------|------|
@@ -442,7 +442,15 @@ PgKit.search_vectors("my_vec", [0.1] * 384, top_k=5, id_col="vid", column="vec")
442
442
  > 新增(非破坏性):`VECTOR_CAPABILITIES` 能力声明、`id_col` / `column` 逃生口参数、
443
443
  > `insert_vectors` 支持二维 numpy 数组与批量提交。
444
444
 
445
- #### 0.2.5 变更(开发中,未发布)
445
+ #### 0.2.6 变更
446
+
447
+ | 编号 | 变更 | 影响 |
448
+ |------|------|------|
449
+ | D1 | `prepare_statement` 的 `params` 支持**参数行列表**(`list[dict]`):**原样返回该列表** → `session.execute(*prepare_statement(sql, params))` 即批量执行(executemany),与 `build_insert_vectors` 的返回形态直接对接;行键集不一致或行值含序列 → 本地可操作 `ValueError`(与 `execute` 批量形态**同一规则**) | 向后兼容:单字典 / `None` 形态行为不变;行列表形态**不做** `IN` 展开(与批量互斥) |
450
+ | D1 | 文档:修正「自有事务」示例——0.2.5 的示例把 `build_insert_vectors` 返回的**行列表**传给了单字典形态,照抄会抛 `AttributeError: 'list' object has no attribute 'items'` | **纯文档缺陷修正**(0.2.5 示例照抄即崩) |
451
+ | — | 文档:批量执行补充 `rowcount` 备注——忽略型写入(如 SQLite `INSERT OR IGNORE`)的冲突行不计入 `rowcount`(即 `rowcount` = 实际插入数;⚠ 仅 SQLite 实测) | 文档 |
452
+
453
+ #### 0.2.5 变更
446
454
 
447
455
  | 编号 | 变更 | 影响 |
448
456
  |------|------|------|
@@ -23,7 +23,7 @@ Author: Clark Chang
23
23
  数据库访问通过 kit.db 子包提供(基于 SQLModel)。
24
24
  """
25
25
 
26
- __version__ = "0.2.5"
26
+ __version__ = "0.2.6"
27
27
 
28
28
  from kit.db import (
29
29
  MYSQL,
@@ -202,14 +202,24 @@ _EXPANDING_TYPES = (list, tuple, set, frozenset)
202
202
 
203
203
 
204
204
  def prepare_statement(
205
- sql: str, params: FieldData | None = None
206
- ) -> tuple[TextClause, FieldData | None]:
207
- """把 SQL 文本 + 参数字典转为(可直接执行的语句, 归一化后的参数)
205
+ sql: str, params: FieldData | builtins.list[FieldData] | None = None
206
+ ) -> tuple[TextClause, FieldData | builtins.list[FieldData] | None]:
207
+ """把 SQL 文本 + 参数转为(可直接执行的语句, 参数)
208
208
 
209
209
  供调用方在**自有事务**(`*Kit.transaction()`)内执行原生 SQL,
210
- 与 ``query`` / ``execute`` 使用**同一实现**(单一事实源)——后两者等价于
211
- ``session.execute(*prepare_statement(sql, params))``;本函数**不建连接、
212
- 不改状态、不执行**。
210
+ 与 ``query`` / ``execute`` 使用**同一套参数规则**(单一事实源)——
211
+ 单字典形态下后两者等价于 ``session.execute(*prepare_statement(sql, params))``;
212
+ 本函数**不建连接、不改状态、不执行**。
213
+
214
+ 两种参数形态(与 ``execute`` 对称):
215
+
216
+ - **单字典**:值为 ``list`` / ``tuple`` / ``set`` / ``frozenset`` 的键按
217
+ SQLAlchemy **expanding** 语义绑定,可直接书写 ``WHERE id IN :ids``
218
+ (三库通用);第二项为归一化后的参数字典;
219
+ - **字典列表**(批量 / executemany):第二项**原样返回该列表**,语句为
220
+ 裸 ``text(sql)``(**不做** ``IN`` 展开——批量与展开参数互斥,与
221
+ ``execute`` 的批量约束一致);经 ``_validate_batch_rows`` 本地预校验
222
+ (各行键集一致、行值为标量)。
213
223
 
214
224
  典型用法(调用方**无须 import sqlalchemy**)::
215
225
 
@@ -221,7 +231,13 @@ def prepare_statement(
221
231
  with SQLiteKit.transaction() as session:
222
232
  session.execute(stmt, bound) # 第二个值必须一并传入
223
233
 
224
- 三条实现约束(与 ``query`` / ``execute`` 现有语义完全一致):
234
+ stmt, rows = prepare_statement( # 批量(executemany)
235
+ "INSERT INTO t (a, b) VALUES (:a, :b)", [{"a": 1, "b": 2}]
236
+ )
237
+ with SQLiteKit.transaction() as session:
238
+ session.execute(stmt, rows)
239
+
240
+ 三条实现约束(**单字典形态**,与 ``query`` / ``execute`` 现有语义完全一致):
225
241
 
226
242
  1. 只对**确实出现在 SQL 文本中**的参数名做 expanding —— 否则传入"未使用的
227
243
  序列参数"会触发 SQLAlchemy 的 ``ArgumentError: This text() construct
@@ -233,20 +249,31 @@ def prepare_statement(
233
249
 
234
250
  Args:
235
251
  sql: SQL 语句(使用命名参数 ``:param``)
236
- params: 参数字典,值为 ``list`` / ``tuple`` / ``set`` / ``frozenset`` 的键
237
- 按 ``IN`` 展开(三库通用)
252
+ params: **单个参数字典**(值为 ``list`` / ``tuple`` / ``set`` / ``frozenset``
253
+ 的键按 ``IN`` 展开,三库通用)或**参数字典的列表**(批量,行值须为标量)
238
254
 
239
255
  Returns:
240
- ``(语句, 归一化后的参数字典)``:执行时**必须**把第二个值一并传给
241
- ``session.execute``;``params`` 为 None 时第二项即 None
256
+ ``(语句, 参数)``:执行时**必须**把第二个值一并传给 ``session.execute``;
257
+ ``params`` 为 None 时第二项即 None,为列表时**原样返回该列表**
242
258
 
243
259
  Note:
244
260
  ``:name::type`` 这类 PostgreSQL 风格 cast **不被 SQLAlchemy 的 ``text()``
245
261
  识别**(该写法在支持本函数之前同样不可用),请改用 ``CAST(:name AS type)``。
246
262
 
263
+ Raises:
264
+ ValueError: 列表形态的行键集不一致或行值含序列类型(来自
265
+ ``_validate_batch_rows``,与 ``execute`` 批量形态同一规则)
266
+
247
267
  See Also:
248
268
  ``query`` / ``execute``:kit 自管事务的原生 SQL 入口(同样支持列表参数)。
249
269
  """
270
+ if isinstance(params, builtins.list):
271
+ # 批量形态:语句不做 IN 展开,参数行列表原样返回(由 execute/session
272
+ # 以 executemany 执行);空列表不校验、不报错(构造期无副作用)
273
+ if params:
274
+ _validate_batch_rows(params)
275
+ return text(sql), params
276
+
250
277
  statement = text(sql)
251
278
  if not params:
252
279
  return statement, params
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes