sqlseed 0.1.10__tar.gz → 0.1.12__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 (86) hide show
  1. {sqlseed-0.1.10 → sqlseed-0.1.12}/.gitignore +4 -3
  2. {sqlseed-0.1.10 → sqlseed-0.1.12}/CHANGELOG.md +8 -2
  3. {sqlseed-0.1.10 → sqlseed-0.1.12}/PKG-INFO +141 -123
  4. {sqlseed-0.1.10 → sqlseed-0.1.12}/README.md +139 -122
  5. {sqlseed-0.1.10 → sqlseed-0.1.12}/plugins/mcp-server-sqlseed/src/mcp_server_sqlseed/server.py +53 -27
  6. {sqlseed-0.1.10 → sqlseed-0.1.12}/plugins/sqlseed-ai/README.md +3 -3
  7. {sqlseed-0.1.10 → sqlseed-0.1.12}/plugins/sqlseed-ai/src/sqlseed_ai/__init__.py +17 -32
  8. sqlseed-0.1.12/plugins/sqlseed-ai/src/sqlseed_ai/_client.py +23 -0
  9. {sqlseed-0.1.10 → sqlseed-0.1.12}/plugins/sqlseed-ai/src/sqlseed_ai/analyzer.py +36 -62
  10. {sqlseed-0.1.10 → sqlseed-0.1.12}/plugins/sqlseed-ai/src/sqlseed_ai/config.py +2 -2
  11. {sqlseed-0.1.10 → sqlseed-0.1.12}/plugins/sqlseed-ai/src/sqlseed_ai/errors.py +64 -32
  12. sqlseed-0.1.12/plugins/sqlseed-ai/src/sqlseed_ai/examples.py +183 -0
  13. sqlseed-0.1.12/plugins/sqlseed-ai/src/sqlseed_ai/provider.py +63 -0
  14. {sqlseed-0.1.10 → sqlseed-0.1.12}/plugins/sqlseed-ai/src/sqlseed_ai/refiner.py +68 -84
  15. {sqlseed-0.1.10 → sqlseed-0.1.12}/pyproject.toml +6 -2
  16. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/__init__.py +10 -7
  17. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/_utils/__init__.py +2 -0
  18. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/_utils/schema_helpers.py +10 -4
  19. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/_utils/sql_safe.py +18 -5
  20. sqlseed-0.1.12/src/sqlseed/_version.py +8 -0
  21. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/cli/__init__.py +2 -0
  22. sqlseed-0.1.12/src/sqlseed/cli/main.py +391 -0
  23. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/config/__init__.py +2 -0
  24. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/config/loader.py +2 -2
  25. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/config/snapshot.py +2 -8
  26. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/core/__init__.py +2 -0
  27. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/core/column_dag.py +49 -39
  28. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/core/constraints.py +46 -20
  29. sqlseed-0.1.12/src/sqlseed/core/enrichment.py +161 -0
  30. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/core/expression.py +10 -10
  31. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/core/mapper.py +77 -33
  32. sqlseed-0.1.12/src/sqlseed/core/orchestrator.py +469 -0
  33. sqlseed-0.1.12/src/sqlseed/core/plugin_mediator.py +162 -0
  34. sqlseed-0.1.12/src/sqlseed/core/relation.py +215 -0
  35. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/core/schema.py +43 -9
  36. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/core/transform.py +7 -7
  37. sqlseed-0.1.12/src/sqlseed/core/unique_adjuster.py +142 -0
  38. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/database/__init__.py +2 -0
  39. sqlseed-0.1.12/src/sqlseed/database/_base_adapter.py +75 -0
  40. sqlseed-0.1.12/src/sqlseed/database/_compat.py +14 -0
  41. sqlseed-0.1.12/src/sqlseed/database/_helpers.py +72 -0
  42. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/database/_protocol.py +1 -1
  43. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/database/optimizer.py +7 -6
  44. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/database/raw_sqlite_adapter.py +24 -77
  45. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/database/sqlite_utils_adapter.py +30 -82
  46. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/generators/__init__.py +4 -1
  47. sqlseed-0.1.12/src/sqlseed/generators/_dispatch.py +41 -0
  48. sqlseed-0.1.12/src/sqlseed/generators/_json_helpers.py +47 -0
  49. sqlseed-0.1.12/src/sqlseed/generators/_protocol.py +22 -0
  50. sqlseed-0.1.12/src/sqlseed/generators/_string_helpers.py +31 -0
  51. sqlseed-0.1.12/src/sqlseed/generators/base_provider.py +355 -0
  52. sqlseed-0.1.12/src/sqlseed/generators/faker_provider.py +129 -0
  53. sqlseed-0.1.12/src/sqlseed/generators/mimesis_provider.py +144 -0
  54. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/generators/registry.py +42 -24
  55. sqlseed-0.1.12/src/sqlseed/generators/stream.py +180 -0
  56. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/plugins/__init__.py +2 -0
  57. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/plugins/hookspecs.py +12 -6
  58. sqlseed-0.1.10/plugins/sqlseed-ai/src/sqlseed_ai/_client.py +0 -31
  59. sqlseed-0.1.10/plugins/sqlseed-ai/src/sqlseed_ai/examples.py +0 -172
  60. sqlseed-0.1.10/plugins/sqlseed-ai/src/sqlseed_ai/nl_config.py +0 -80
  61. sqlseed-0.1.10/plugins/sqlseed-ai/src/sqlseed_ai/provider.py +0 -88
  62. sqlseed-0.1.10/plugins/sqlseed-ai/src/sqlseed_ai/suggest.py +0 -62
  63. sqlseed-0.1.10/src/sqlseed/_version.py +0 -1
  64. sqlseed-0.1.10/src/sqlseed/cli/main.py +0 -319
  65. sqlseed-0.1.10/src/sqlseed/core/orchestrator.py +0 -851
  66. sqlseed-0.1.10/src/sqlseed/core/relation.py +0 -124
  67. sqlseed-0.1.10/src/sqlseed/generators/_protocol.py +0 -73
  68. sqlseed-0.1.10/src/sqlseed/generators/base_provider.py +0 -448
  69. sqlseed-0.1.10/src/sqlseed/generators/faker_provider.py +0 -157
  70. sqlseed-0.1.10/src/sqlseed/generators/mimesis_provider.py +0 -203
  71. sqlseed-0.1.10/src/sqlseed/generators/stream.py +0 -157
  72. {sqlseed-0.1.10 → sqlseed-0.1.12}/LICENSE +0 -0
  73. {sqlseed-0.1.10 → sqlseed-0.1.12}/plugins/mcp-server-sqlseed/README.md +0 -0
  74. {sqlseed-0.1.10 → sqlseed-0.1.12}/plugins/mcp-server-sqlseed/pyproject.toml +0 -0
  75. {sqlseed-0.1.10 → sqlseed-0.1.12}/plugins/mcp-server-sqlseed/src/mcp_server_sqlseed/__init__.py +0 -0
  76. {sqlseed-0.1.10 → sqlseed-0.1.12}/plugins/mcp-server-sqlseed/src/mcp_server_sqlseed/__main__.py +0 -0
  77. {sqlseed-0.1.10 → sqlseed-0.1.12}/plugins/mcp-server-sqlseed/src/mcp_server_sqlseed/config.py +0 -0
  78. {sqlseed-0.1.10 → sqlseed-0.1.12}/plugins/sqlseed-ai/pyproject.toml +0 -0
  79. {sqlseed-0.1.10 → sqlseed-0.1.12}/plugins/sqlseed-ai/src/sqlseed_ai/_json_utils.py +0 -0
  80. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/_utils/logger.py +0 -0
  81. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/_utils/metrics.py +0 -0
  82. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/_utils/progress.py +0 -0
  83. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/config/models.py +0 -0
  84. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/core/result.py +0 -0
  85. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/plugins/manager.py +0 -0
  86. {sqlseed-0.1.10 → sqlseed-0.1.12}/src/sqlseed/py.typed +0 -0
@@ -35,6 +35,7 @@ ENV/
35
35
  # Testing
36
36
  .pytest_cache/
37
37
  .coverage
38
+ coverage.xml
38
39
  htmlcov/
39
40
 
40
41
  # Type checking
@@ -54,9 +55,6 @@ snapshots/
54
55
  # AI cache
55
56
  .sqlseed_cache/
56
57
 
57
- # Archived temp files
58
- _archived_temp/
59
-
60
58
  # macOS
61
59
  .DS_Store
62
60
 
@@ -67,3 +65,6 @@ _archived_temp/
67
65
  dist/
68
66
  *.whl
69
67
  *.tar.gz
68
+
69
+ # Local git worktrees
70
+ .worktrees/
@@ -17,7 +17,7 @@
17
17
  - `DataProvider` Protocol,含 `BaseProvider`、`FakerProvider`、`MimesisProvider`
18
18
  - `DataStream` 流式数据生成器,内存高效的批量处理
19
19
  - `RelationResolver` 外键依赖拓扑排序
20
- - 基于 `pluggy` 的插件系统,10 个 Hook 点
20
+ - 基于 `pluggy` 的插件系统,11 个 Hook 点
21
21
  - CLI 命令:`fill`、`preview`、`inspect`、`init`、`replay`、`ai-suggest`
22
22
  - Python API:`sqlseed.fill()`、`sqlseed.connect()`、`sqlseed.fill_from_config()`、`sqlseed.preview()`
23
23
  - YAML/JSON 配置文件支持
@@ -41,7 +41,7 @@
41
41
  - `AIConfig` 可配置模型、API Key 和 Base URL
42
42
  - 默认模型:`qwen3-coder-plus`,支持环境变量覆盖
43
43
  - CLI `ai-suggest` 命令,AI 驱动的 YAML 生成
44
- - 自然语言配置(`nl_config.py`)
44
+ - 自然语言配置(`nl_config.py`,已移除,功能由 `SchemaAnalyzer` + `AiConfigRefiner` 替代)
45
45
 
46
46
  #### AI Evolution — 智能增强
47
47
  - 结构化输出迁移:YAML → JSON,`response_format` 强制 JSON 输出
@@ -78,3 +78,9 @@
78
78
  - 表达式引擎增加超时保护(默认 5 秒),防止无限循环
79
79
  - 解决 `random.seed()` 类型异常(`rstr` 集成于流式生成器)
80
80
  - `fill_from_config` 中 transform 属性正确传递到内部编排器
81
+ - `ProviderRegistry.register_from_entry_points()` 修正 provider 类与普通插件入口点的区分逻辑,非 provider 入口点(如 `sqlseed_ai:plugin`)不再产生误报 warning
82
+
83
+ ### 变更
84
+ - README / 开发文档与当前实现对齐:MCP tool 名称、Provider 协议示例、`sqlseed_shared_pool_loaded` 触发时机与 `UnknownGeneratorError` 行为说明已同步
85
+ - 移除 `suggest.py`(`ColumnSuggester`)和 `nl_config.py`(`NLConfigGenerator`),其功能由 `SchemaAnalyzer` + `AiConfigRefiner` 完全替代。如有外部代码直接 `from sqlseed_ai.suggest import ColumnSuggester` 或 `from sqlseed_ai.nl_config import NLConfigGenerator`,将产生 `ImportError`
86
+ - `plugins/sqlseed-ai/README.md` 功能描述与当前实际入口对齐,移除未对外提供的 "Column-level Suggestions" / "Natural Language Config" 描述
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlseed
3
- Version: 0.1.10
3
+ Version: 0.1.12
4
4
  Summary: Declarative SQLite test data generation toolkit
5
5
  Project-URL: Homepage, https://github.com/sunbos/sqlseed
6
6
  Project-URL: Documentation, https://github.com/sunbos/sqlseed#readme
@@ -38,6 +38,7 @@ Provides-Extra: dev
38
38
  Requires-Dist: mypy>=1.10; extra == 'dev'
39
39
  Requires-Dist: pre-commit>=3.0; extra == 'dev'
40
40
  Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
41
+ Requires-Dist: pytest-benchmark>=4.0; extra == 'dev'
41
42
  Requires-Dist: pytest-cov>=5.0; extra == 'dev'
42
43
  Requires-Dist: pytest>=8.0; extra == 'dev'
43
44
  Requires-Dist: ruff>=0.5; extra == 'dev'
@@ -56,17 +57,17 @@ Description-Content-Type: text/markdown
56
57
 
57
58
  ### 声明式 SQLite 测试数据生成工具包
58
59
 
59
- **一行代码,十万行数据。零配置智能生成,AI 驱动精准调优。**
60
+ **一行代码,数万行数据。零配置智能生成,AI 驱动精准调优。**
60
61
 
61
62
  [![CI](https://github.com/sunbos/sqlseed/actions/workflows/ci.yml/badge.svg)](https://github.com/sunbos/sqlseed/actions)
62
- [![Python 3.10+](https://img.shields.io/badge/python-3.10+-3776ab.svg?logo=python&logoColor=white)](https://www.python.org/downloads/)
63
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-3776ab.svg?logo=python\&logoColor=white)](https://www.python.org/downloads/)
63
64
  [![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
64
65
  [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
65
66
  [![Type: mypy](https://img.shields.io/badge/type%20checker-mypy-blue.svg)](https://mypy-lang.org/)
66
67
 
67
68
  </div>
68
69
 
69
- ---
70
+ ***
70
71
 
71
72
  ```python
72
73
  import sqlseed
@@ -77,21 +78,21 @@ print(result)
77
78
  # → GenerationResult(table=users, count=100000, elapsed=2.34s, speed=42735 rows/s)
78
79
  ```
79
80
 
80
- ---
81
+ ***
81
82
 
82
83
  ## 💡 为什么选择 sqlseed?
83
84
 
84
85
  在开发和测试流程中,我们经常需要为 SQLite 数据库填充大量真实感的测试数据。传统方式要么手写冗长的数据生成脚本,要么使用难以维护的 SQL fixtures。sqlseed 用一种全新的声明式方式解决了这个问题:
85
86
 
86
- | 特性 | sqlseed | 手写脚本 | SQL Fixtures |
87
- |:---|:---:|:---:|:---:|
88
- | 零配置智能生成 | | | |
89
- | 外键自动维护 | | 手动 | 手动 |
90
- | 10 万行 + 数据 | ✅ 流式 | ⚠️ OOM | |
91
- | 列语义推断 | ✅ 8 级策略 | | |
92
- | 可重复生成 | ✅ seed | ⚠️ 手动 | |
93
- | AI 智能调优 | ✅ LLM | | |
94
- | 配置热重用 | ✅ YAML | | |
87
+ | 特性 | sqlseed | 手写脚本 | SQL Fixtures |
88
+ | :--------- | :-----: | :----: | :----------: |
89
+ | 零配置智能生成 | | | |
90
+ | 外键自动维护 | | 手动 | 手动 |
91
+ | 10 万行 + 数据 | ✅ 流式 | ⚠️ OOM | |
92
+ | 列语义推断 | ✅ 9 级策略 | | |
93
+ | 可重复生成 | ✅ seed | ⚠️ 手动 | |
94
+ | AI 智能调优 | ✅ LLM | | |
95
+ | 配置热重用 | ✅ YAML | | |
95
96
 
96
97
  ## ✨ 核心特性
97
98
 
@@ -101,7 +102,7 @@ print(result)
101
102
 
102
103
  **🚀 零配置智能生成**
103
104
 
104
- 自动推断数据库 Schema,通过 8 级策略链为每列选择最佳生成器。列名是 `email`?生成邮箱。列名是 `*_at`?生成时间戳。完全不需要配置。
105
+ 自动推断数据库 Schema,通过 9 级策略链为每列选择最佳生成器。列名是 `email`?生成邮箱。列名是 `*_at`?生成时间戳。完全不需要配置。
105
106
 
106
107
  </td>
107
108
  <td width="50%">
@@ -162,7 +163,7 @@ print(result)
162
163
  </tr>
163
164
  </table>
164
165
 
165
- ---
166
+ ***
166
167
 
167
168
  ## 📦 安装
168
169
 
@@ -217,7 +218,7 @@ mypy src/sqlseed/
217
218
 
218
219
  </details>
219
220
 
220
- ---
221
+ ***
221
222
 
222
223
  ## 🚀 快速开始
223
224
 
@@ -249,18 +250,19 @@ print(result)
249
250
  ```
250
251
 
251
252
  sqlseed 会自动:
253
+
252
254
  - ✅ 跳过 `id`(自增主键)
253
255
  - ✅ 跳过 `is_active`(有默认值)
254
256
  - ✅ `name` → 生成真实姓名
255
257
  - ✅ `email` → 生成邮箱地址
256
- - ✅ `age` → 生成 18~100 的整数
258
+ - ✅ `age` → 生成 18\~100 的整数
257
259
  - ✅ `phone` → 生成电话号码
258
260
  - ✅ `created_at` → 生成日期时间(匹配 `*_at` 模式)
259
261
  - ✅ `balance` → 生成浮点数
260
262
 
261
263
  **完全零配置,智能推断一切。**
262
264
 
263
- ---
265
+ ***
264
266
 
265
267
  ## 📖 使用教程
266
268
 
@@ -298,36 +300,36 @@ print(result)
298
300
 
299
301
  #### 支持的生成器类型
300
302
 
301
- | 生成器 | 说明 | 参数示例 |
302
- |:---|:---|:---|
303
- | `string` | 随机字符串 | `min_length`, `max_length`, `charset` |
304
- | `integer` | 整数 | `min_value`, `max_value` |
305
- | `float` | 浮点数 | `min_value`, `max_value`, `precision` |
306
- | `boolean` | 布尔值 | — |
307
- | `name` | 人名 | — |
308
- | `first_name` | 名 | — |
309
- | `last_name` | 姓 | — |
310
- | `email` | 邮箱 | — |
311
- | `phone` | 电话 | — |
312
- | `address` | 地址 | — |
313
- | `company` | 公司名 | — |
314
- | `url` | URL | — |
315
- | `ipv4` | IPv4 地址 | — |
316
- | `uuid` | UUID | — |
317
- | `date` | 日期 | `start_year`, `end_year` |
318
- | `datetime` | 日期时间 | `start_year`, `end_year` |
319
- | `timestamp` | Unix 时间戳 | — |
320
- | `text` | 长文本 | `min_length`, `max_length` |
321
- | `sentence` | 句子 | — |
322
- | `password` | 密码 | `length` |
323
- | `choice` | 从列表选择 | `choices` |
324
- | `json` | JSON 字符串 | `schema` |
325
- | `pattern` | 正则匹配 | `regex` |
326
- | `bytes` | 二进制数据 | `length` |
327
- | `foreign_key` | 外键引用 | `ref_table`, `ref_column`, `strategy` |
328
- | `skip` | 跳过(使用默认值/NULL)| |
329
-
330
- ---
303
+ | 生成器 | 说明 | 参数示例 |
304
+ | :------------ | :------------- | :------------------------------------ |
305
+ | `string` | 随机字符串 | `min_length`, `max_length`, `charset` |
306
+ | `integer` | 整数 | `min_value`, `max_value` |
307
+ | `float` | 浮点数 | `min_value`, `max_value`, `precision` |
308
+ | `boolean` | 布尔值 | — |
309
+ | `name` | 人名 | — |
310
+ | `first_name` | 名 | — |
311
+ | `last_name` | 姓 | — |
312
+ | `email` | 邮箱 | — |
313
+ | `phone` | 电话 | — |
314
+ | `address` | 地址 | — |
315
+ | `company` | 公司名 | — |
316
+ | `url` | URL | — |
317
+ | `ipv4` | IPv4 地址 | — |
318
+ | `uuid` | UUID | — |
319
+ | `date` | 日期 | `start_year`, `end_year` |
320
+ | `datetime` | 日期时间 | `start_year`, `end_year` |
321
+ | `timestamp` | Unix 时间戳 | — |
322
+ | `text` | 长文本 | `min_length`, `max_length` |
323
+ | `sentence` | 句子 | — |
324
+ | `password` | 密码 | `length` |
325
+ | `choice` | 从列表选择 | `choices` |
326
+ | `json` | JSON 字符串 | `schema` |
327
+ | `pattern` | 正则匹配 | `regex` |
328
+ | `bytes` | 二进制数据 | `length` |
329
+ | `foreign_key` | 外键引用 | `ref_table`, `ref_column`, `strategy` |
330
+ | `skip` | 跳过(使用默认值/NULL | |
331
+
332
+ ***
331
333
 
332
334
  ### 教程 2:多表关联 — 自动维持外键完整性
333
335
 
@@ -358,7 +360,7 @@ with sqlseed.connect("app.db", provider="mimesis", locale="zh_CN") as db:
358
360
 
359
361
  > **💡 提示**:如果两张表之间有同名列(如 `account_id`),即使没有声明外键约束,sqlseed 也会通过 **SharedPool 隐式关联机制**自动维持跨表一致性。
360
362
 
361
- ---
363
+ ***
362
364
 
363
365
  ### 教程 3:YAML 配置文件驱动批量生成
364
366
 
@@ -438,7 +440,7 @@ for r in results:
438
440
  print(r)
439
441
  ```
440
442
 
441
- ---
443
+ ***
442
444
 
443
445
  ### 教程 4:派生列与表达式引擎
444
446
 
@@ -476,6 +478,7 @@ tables:
476
478
  ```
477
479
 
478
480
  **运作原理**:
481
+
479
482
  1. sqlseed 构建列依赖 DAG:`card_number → last_eight, last_six`
480
483
  2. 拓扑排序确定生成顺序
481
484
  3. 先生成 `card_number`,再通过表达式 `value[-8:]` 计算 `last_eight`
@@ -483,26 +486,26 @@ tables:
483
486
 
484
487
  #### 表达式引擎支持的函数
485
488
 
486
- | 函数 | 用法 | 说明 |
487
- |:---|:---|:---|
488
- | `upper(s)` | `upper(value)` | 转大写 |
489
- | `lower(s)` | `lower(value)` | 转小写 |
490
- | `len(s)` | `len(value)` | 获取长度 |
491
- | `substr(s, start, end)` | `substr(value, 0, 8)` | 子串 |
492
- | `concat(*args)` | `concat("PRE_", value)` | 拼接 |
493
- | `zfill(s, width)` | `zfill(value, 10)` | 零填充 |
494
- | `lpad(s, width, char)` | `lpad(value, 8, "0")` | 左填充 |
495
- | `rpad(s, width, char)` | `rpad(value, 8, "0")` | 右填充 |
496
- | `replace(s, old, new)` | `replace(value, "-", "")` | 替换 |
497
- | `strip(s)` | `strip(value)` | 去空白 |
498
- | `int(s)` | `int(value)` | 转整数 |
499
- | `str(s)` | `str(value)` | 转字符串 |
500
- | 切片 | `value[-8:]` | Python 切片语法 |
501
- | 数学 | `value * 2 + 1` | 基本数学运算 |
489
+ | 函数 | 用法 | 说明 |
490
+ | :---------------------- | :------------------------ | :---------- |
491
+ | `upper(s)` | `upper(value)` | 转大写 |
492
+ | `lower(s)` | `lower(value)` | 转小写 |
493
+ | `len(s)` | `len(value)` | 获取长度 |
494
+ | `substr(s, start, end)` | `substr(value, 0, 8)` | 子串 |
495
+ | `concat(*args)` | `concat("PRE_", value)` | 拼接 |
496
+ | `zfill(s, width)` | `zfill(value, 10)` | 零填充 |
497
+ | `lpad(s, width, char)` | `lpad(value, 8, "0")` | 左填充 |
498
+ | `rpad(s, width, char)` | `rpad(value, 8, "0")` | 右填充 |
499
+ | `replace(s, old, new)` | `replace(value, "-", "")` | 替换 |
500
+ | `strip(s)` | `strip(value)` | 去空白 |
501
+ | `int(s)` | `int(value)` | 转整数 |
502
+ | `str(s)` | `str(value)` | 转字符串 |
503
+ | 切片 | `value[-8:]` | Python 切片语法 |
504
+ | 数学 | `value * 2 + 1` | 基本数学运算 |
502
505
 
503
506
  > ⚠️ **安全保护**:表达式引擎基于 `simpleeval`,具有 5 秒超时保护,不允许 `import`、`exec` 或文件 I/O 操作。
504
507
 
505
- ---
508
+ ***
506
509
 
507
510
  ### 教程 5:Transform 脚本 — 极端业务逻辑
508
511
 
@@ -547,7 +550,7 @@ tables:
547
550
  transform: "./transform_users.py"
548
551
  ```
549
552
 
550
- ---
553
+ ***
551
554
 
552
555
  ### 教程 6:预览与调试
553
556
 
@@ -594,7 +597,7 @@ sqlseed inspect app.db --table users --show-mapping
594
597
  # └────────────┴─────────┴──────────┴──────────────┴──────────────┘
595
598
  ```
596
599
 
597
- ---
600
+ ***
598
601
 
599
602
  ### 教程 7:快照与回放
600
603
 
@@ -611,11 +614,12 @@ sqlseed replay snapshots/2026-04-15_033000_users.yaml
611
614
  ```
612
615
 
613
616
  适用场景:
617
+
614
618
  - 🧪 CI/CD 中需要可重复的测试数据
615
619
  - 📋 团队间共享一致的测试环境
616
620
  - 🔄 开发时快速重建数据库状态
617
621
 
618
- ---
622
+ ***
619
623
 
620
624
  ### 教程 8:AI 智能配置(sqlseed-ai 插件)
621
625
 
@@ -655,7 +659,7 @@ sqlseed ai-suggest app.db --table bank_cards --output bank_cards.yaml --no-cache
655
659
 
656
660
  > **💡 环境变量**:支持 `SQLSEED_AI_API_KEY`、`SQLSEED_AI_BASE_URL`、`SQLSEED_AI_MODEL`。默认模型为 `qwen3-coder-plus`。
657
661
 
658
- ---
662
+ ***
659
663
 
660
664
  ### 教程 9:MCP 服务器集成
661
665
 
@@ -671,20 +675,20 @@ python -m mcp_server_sqlseed
671
675
 
672
676
  **MCP 提供的能力**:
673
677
 
674
- | 类型 | 名称 | 说明 |
675
- |:---|:---|:---|
676
- | 📖 Resource | `sqlseed://schema/{db_path}/{table_name}` | 获取表 Schema 的 JSON 表示 |
677
- | 🔍 Tool | `sqlseed_inspect_schema` | 检查 Schema(列、外键、索引、样本数据、schema_hash) |
678
- | 🤖 Tool | `sqlseed_generate_yaml` | AI 驱动的 YAML 配置生成(含自纠正) |
679
- | ⚡ Tool | `sqlseed_execute_fill` | 执行数据生成(支持 YAML 配置字符串) |
678
+ | 类型 | 名称 | 说明 |
679
+ | :---------- | :---------------------------------------- | :----------------------------------- |
680
+ | 📖 Resource | `sqlseed://schema/{db_path}/{table_name}` | 获取表 Schema 的 JSON 表示 |
681
+ | 🔍 Tool | `sqlseed_inspect_schema` | 检查 Schema(列、外键、索引、样本数据、schema\_hash) |
682
+ | 🤖 Tool | `sqlseed_generate_yaml` | AI 驱动的 YAML 配置生成(含自纠正) |
683
+ | ⚡ Tool | `sqlseed_execute_fill` | 执行数据生成(支持 YAML 配置字符串) |
680
684
 
681
685
  这意味着你可以在 AI 助手中说:
682
686
 
683
687
  > "分析 `app.db` 中 `bank_cards` 表的结构,生成 YAML 配置,然后填充 5000 行数据。"
684
688
 
685
- AI 助手会依次调用 `inspect_schema` → `generate_yaml` → `execute_fill`,无需你手动编写任何代码。
689
+ AI 助手会依次调用 `sqlseed_inspect_schema` → `sqlseed_generate_yaml` → `sqlseed_execute_fill`,无需你手动编写任何代码。
686
690
 
687
- ---
691
+ ***
688
692
 
689
693
  ### 教程 10:自定义 Provider 插件
690
694
 
@@ -695,6 +699,8 @@ AI 助手会依次调用 `inspect_schema` → `generate_yaml` → `execute_fill`
695
699
  from __future__ import annotations
696
700
  from typing import Any
697
701
 
702
+ from sqlseed.generators import UnknownGeneratorError
703
+
698
704
  class MyCustomProvider:
699
705
  """实现 DataProvider Protocol 即可。不需要继承任何基类。"""
700
706
 
@@ -711,14 +717,20 @@ class MyCustomProvider:
711
717
  def set_seed(self, seed: int) -> None:
712
718
  ...
713
719
 
714
- def generate_string(self, *, min_length: int = 1, max_length: int = 100, charset: str | None = None) -> str:
715
- return "custom_string"
720
+ def generate(self, type_name: str, **params: Any) -> Any:
721
+ if type_name == "string":
722
+ return "custom_string"
723
+ if type_name == "email":
724
+ return "user@example.com"
725
+ raise UnknownGeneratorError(type_name)
716
726
 
717
- # ... 实现其余 generate_* 方法
727
+ # ... 按需处理你要支持的 generator 名称
718
728
  # 完整 Protocol 参见:src/sqlseed/generators/_protocol.py
719
729
  ```
720
730
 
721
- **注册方式 1:通过 `pyproject.toml` entry-point(推荐)**
731
+ 如果你想复用内置的 generator name 分发逻辑,而不是手写 `generate()` 的路由,也可以直接继承 `BaseProvider` 后覆盖局部行为。
732
+
733
+ **注册方式 1:通过** **`pyproject.toml`** **entry-point(推荐)**
722
734
 
723
735
  ```toml
724
736
  [project.entry-points."sqlseed"]
@@ -737,7 +749,7 @@ class MyPlugin:
737
749
  registry.register(MyCustomProvider())
738
750
  ```
739
751
 
740
- ---
752
+ ***
741
753
 
742
754
  ## 🖥️ CLI 命令速查
743
755
 
@@ -746,7 +758,7 @@ class MyPlugin:
746
758
  # 📋 数据生成
747
759
  # ═══════════════════════════════════════
748
760
 
749
- # 零配置填充
761
+ # 填充数据(--count 在非 --config 模式下必填)
750
762
  sqlseed fill app.db --table users --count 10000
751
763
 
752
764
  # 完整参数
@@ -758,12 +770,15 @@ sqlseed fill app.db -t users -n 100000 \
758
770
  --clear \
759
771
  --snapshot
760
772
 
761
- # YAML 配置驱动
773
+ # YAML 配置驱动(count 来自配置文件)
762
774
  sqlseed fill --config generate.yaml
763
775
 
764
776
  # Transform 脚本
765
777
  sqlseed fill app.db -t users -n 10000 --transform transform.py
766
778
 
779
+ # 开启 debug 日志
780
+ SQLSEED_LOG_LEVEL=DEBUG sqlseed fill app.db -t users -n 10
781
+
767
782
  # ═══════════════════════════════════════
768
783
  # 🔍 查看与预览
769
784
  # ═══════════════════════════════════════
@@ -796,58 +811,61 @@ sqlseed ai-suggest app.db -t users -o users.yaml
796
811
  sqlseed ai-suggest app.db -t users -o users.yaml --model gpt-4o --verify
797
812
  ```
798
813
 
799
- ---
814
+ ***
800
815
 
801
- ## 🧠 8 级智能列映射
816
+ ## 🧠 9 级智能列映射
802
817
 
803
- sqlseed 的核心亮点之一是 `ColumnMapper` 的 8 级策略链。每一列都会按以下优先级尝试匹配:
818
+ sqlseed 的核心亮点之一是 `ColumnMapper` 的 9 级策略链。每一列都会按以下优先级尝试匹配:
804
819
 
805
820
  ```
806
821
  Level 1 │ 用户配置 columns={"email": "email"} 最高优先级
807
822
 
808
823
  Level 2 │ 自定义精确匹配 通过插件 Hook 注册的规则
809
824
 
810
- Level 3 │ 内置精确匹配 67 条规则:email→email, phone→phone, age→integer...
825
+ Level 3 │ 内置精确匹配 68 条规则:email→email, phone→phone, age→integer...
826
+
827
+ Level 4 │ DEFAULT 检查 有默认值 → skip(精确匹配优先于 DEFAULT)
811
828
 
812
- Level 4 │ 自定义模式匹配 通过插件 Hook 注册的正则规则
829
+ Level 5 │ 自定义模式匹配 通过插件 Hook 注册的正则规则
813
830
 
814
- Level 5 │ 内置模式匹配 25 条正则:*_at→datetime, *_id→foreign_key, is_*→boolean...
831
+ Level 6 │ 内置模式匹配 25 条正则:*_at→datetime, *_id→foreign_key, is_*→boolean...
815
832
 
816
- Level 6跳过 有默认值或可 NULL → skip
833
+ Level 7NULLABLE 回退 可 NULL → skip
817
834
 
818
- Level 7 │ 类型忠实回退 VARCHAR(32)→最长32字符, INT8→0~255, BLOB(1024)→1024字节
835
+ Level 8 │ 类型忠实回退 VARCHAR(32)→最长32字符, INT8→0~255, BLOB(1024)→1024字节
819
836
 
820
- Level 8 │ 默认 string (min=5, max=50)
837
+ Level 9 │ 默认 string (min=5, max=50)
821
838
  ```
822
839
 
823
840
  这意味着:
824
841
 
825
- - 列名 `user_email` → Level 5 模式匹配 `*_email` → `email` 生成器 ✅
826
- - 列名 `is_verified` → Level 5 模式匹配 `is_*` → `boolean` 生成器 ✅
827
- - 列类型 `VARCHAR(20)` → Level 7 类型回退 → 最长 20 字符的字符串 ✅
828
- - 列有 `DEFAULT 1` → Level 6 → 跳过生成 ✅
842
+ - 列名 `user_email` → Level 6 模式匹配 `*_email` → `email` 生成器 ✅
843
+ - 列名 `is_verified` → Level 6 模式匹配 `is_*` → `boolean` 生成器 ✅
844
+ - 列类型 `VARCHAR(20)` → Level 8 类型回退 → 最长 20 字符的字符串 ✅
845
+ - 列有 `DEFAULT 1` → Level 4 → 跳过生成 ✅
846
+ - 列名 `gender` 有 `DEFAULT 'male'` → Level 3 精确匹配 → `choice` 生成器(精确匹配优先于 DEFAULT)✅
829
847
 
830
- ---
848
+ ***
831
849
 
832
850
  ## 🧩 插件系统
833
851
 
834
852
  sqlseed 通过 [pluggy](https://pluggy.readthedocs.io/) 提供 11 个 Hook 点,覆盖数据生成全生命周期:
835
853
 
836
- | Hook | firstresult | 触发时机 |
837
- |:---|:---:|:---|
838
- | `sqlseed_register_providers` | | 注册自定义数据 Provider |
839
- | `sqlseed_register_column_mappers` | | 注册自定义列映射规则 |
840
- | `sqlseed_ai_analyze_table` | | AI 分析表 Schema(返回列配置建议) |
841
- | `sqlseed_pre_generate_templates` | | AI 预计算候选值池 |
842
- | `sqlseed_before_generate` | | 数据生成循环前 |
843
- | `sqlseed_after_generate` | | 数据生成完成后 |
844
- | `sqlseed_transform_row` | | 逐行变换(热路径,注意性能) |
845
- | `sqlseed_transform_batch` | | 逐批变换(支持链式处理) |
846
- | `sqlseed_before_insert` | | 每批写入 DB 前 |
847
- | `sqlseed_after_insert` | | 每批写入 DB 后 |
848
- | `sqlseed_shared_pool_loaded` | | 跨表共享池加载完成 |
849
-
850
- ---
854
+ | Hook | firstresult | 触发时机 |
855
+ | :-------------------------------- | :---------: | :--------------------- |
856
+ | `sqlseed_register_providers` | <br /> | 注册自定义数据 Provider |
857
+ | `sqlseed_register_column_mappers` | <br /> | 注册自定义列映射规则 |
858
+ | `sqlseed_ai_analyze_table` | | AI 分析表 Schema(返回列配置建议) |
859
+ | `sqlseed_pre_generate_templates` | | AI 预计算候选值池 |
860
+ | `sqlseed_before_generate` | <br /> | 数据生成循环前 |
861
+ | `sqlseed_after_generate` | <br /> | 数据生成完成后 |
862
+ | `sqlseed_transform_row` | <br /> | 逐行变换(热路径,注意性能) |
863
+ | `sqlseed_transform_batch` | <br /> | 逐批变换(支持链式处理) |
864
+ | `sqlseed_before_insert` | <br /> | 每批写入 DB 前 |
865
+ | `sqlseed_after_insert` | <br /> | 每批写入 DB 后 |
866
+ | `sqlseed_shared_pool_loaded` | <br /> | SharedPool 注册后(值池已可读) |
867
+
868
+ ***
851
869
 
852
870
  ## 🏗️ 项目架构
853
871
 
@@ -856,7 +874,7 @@ src/sqlseed/
856
874
  ├── __init__.py # 公共 API (fill, connect, fill_from_config, preview)
857
875
  ├── core/ # ===== 核心编排层 =====
858
876
  │ ├── orchestrator.py # DataOrchestrator 主引擎
859
- │ ├── mapper.py # ColumnMapper 8 级策略链
877
+ │ ├── mapper.py # ColumnMapper 9 级策略链
860
878
  │ ├── schema.py # SchemaInferrer — 推断列、索引、数据分布
861
879
  │ ├── relation.py # RelationResolver + SharedPool — FK 与跨表共享
862
880
  │ ├── column_dag.py # ColumnDAG — 列依赖图 + 拓扑排序
@@ -865,12 +883,12 @@ src/sqlseed/
865
883
  │ ├── transform.py # TransformLoader — 用户脚本动态加载
866
884
  │ └── result.py # GenerationResult 数据类
867
885
  ├── generators/ # ===== 数据生成层 =====
868
- │ ├── _protocol.py # DataProvider Protocol (24 个 generate_* 方法)
886
+ │ ├── _protocol.py # DataProvider Protocol + UnknownGeneratorError
869
887
  │ ├── registry.py # ProviderRegistry (entry-point 自动发现)
870
888
  │ ├── base_provider.py # 内置基础生成器(零依赖)
871
889
  │ ├── faker_provider.py # Faker 适配器
872
890
  │ ├── mimesis_provider.py # Mimesis 适配器
873
- │ └── stream.py # DataStream 流式生成 + 约束回溯
891
+ │ └── stream.py # DataStream 流式生成 + 约束回溯 + choice/foreign_key 特判
874
892
  ├── database/ # ===== 数据库层 =====
875
893
  │ ├── _protocol.py # DatabaseAdapter Protocol (ColumnInfo, ForeignKeyInfo, IndexInfo)
876
894
  │ ├── sqlite_utils_adapter.py # 默认适配器
@@ -896,10 +914,10 @@ plugins/
896
914
  ├── sqlseed-ai/ # AI 插件 — LLM 驱动的智能配置
897
915
  │ └── src/sqlseed_ai/ # SchemaAnalyzer, AiConfigRefiner, Few-shot 示例...
898
916
  └── mcp-server-sqlseed/ # MCP 服务器 — AI 助手交互
899
- └── src/mcp_server_sqlseed/ # FastMCP 工具 (inspect/generate_yaml/execute_fill)
917
+ └── src/mcp_server_sqlseed/ # FastMCP 工具 (sqlseed_inspect_schema/sqlseed_generate_yaml/sqlseed_execute_fill)
900
918
  ```
901
919
 
902
- ---
920
+ ***
903
921
 
904
922
  ## 🛠️ 开发
905
923
 
@@ -919,13 +937,13 @@ mypy src/sqlseed/
919
937
 
920
938
  测试覆盖了所有核心模块,路径结构与 `src/` 一一对应:`test_core/`、`test_database/`、`test_generators/`、`test_plugins/`、`test_config/`、`test_utils/`。
921
939
 
922
- ---
940
+ ***
923
941
 
924
942
  ## 📄 License
925
943
 
926
944
  [AGPL-3.0-or-later](LICENSE)
927
945
 
928
- ---
946
+ ***
929
947
 
930
948
  <div align="center">
931
949