xls2ddl/aidocs/xls2ddl.md
2025-10-12 13:57:44 +08:00

277 lines
7.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 技术文档Excel/JSON 模型转 DDL 脚本工具
## 简介
本工具是一个基于 Python 的命令行程序,用于将 Excel`.xlsx`)或 JSON 格式的数据模型文件转换为指定数据库类型的 SQL DDL数据定义语言建表语句。支持多种主流数据库包括
- SQL Server
- MySQL
- Oracle
- PostgreSQL
此外,工具还支持根据数据生成 `INSERT` 语句,便于初始化测试数据。
---
## 功能特性
| 特性 | 描述 |
|------|------|
| 多格式输入 | 支持 `.xlsx``.json` 文件作为输入源 |
| 多数据库输出 | 支持生成四种数据库的 DDL 语法 |
| 模板驱动 | 使用模板引擎自定义 DDL 输出格式 |
| 自动生成插入语句 | 若模型中包含数据,自动附加 `INSERT INTO` 语句 |
| 批量处理 | 可遍历整个目录下的所有模型文件并合并输出 |
---
## 目录结构与依赖说明
### 项目依赖模块
```python
import io
import sys
from traceback import print_exc
from xlsxData import CRUDData, xlsxFactory
import codecs
import json
from sqlor.ddl_template_sqlserver import sqlserver_ddl_tmpl
from sqlor.ddl_template_mysql import mysql_ddl_tmpl
from sqlor.ddl_template_oracle import oracle_ddl_tmpl
from sqlor.ddl_template_postgresql import postgresql_ddl_tmpl
from appPublic.myTE import MyTemplateEngine
from appPublic.folderUtils import listFile
```
> **注意**
> - `xlsxData`:负责读取 `.xlsx` 文件并解析成结构化数据。
> - `sqlor.*_ddl_tmpl`:各数据库对应的 DDL 模板字符串。
> - `appPublic.myTE.MyTemplateEngine`:轻量级模板渲染引擎。
> - `appPublic.folderUtils.listFile`:递归列出指定后缀的文件。
---
## 核心函数说明
### 1. `xls2ddl(xlsfile: str, dbtype: str) -> str`
将单个 `.xlsx``.json` 文件转换为对应数据库的 DDL 脚本。
#### 参数
| 参数名 | 类型 | 说明 |
|-------|------|------|
| `xlsfile` | `str` | 输入文件路径(支持 `.xlsx``.json` |
| `dbtype` | `str` | 目标数据库类型,如 `"mysql"``"oracle"` 等(不区分大小写) |
#### 返回值
- 成功时返回完整的 DDL 字符串(含可选的 `INSERT` 语句)
- 失败时打印错误信息并返回 `None`
#### 工作流程
1. 判断文件是否为 JSON
- 是 → 使用 `codecs.open` 以 UTF-8 编码加载 JSON 数据
- 否 → 使用 `xlsxFactory` 创建解析器对象读取 XLSX
2. 获取数据内容 (`data = d.get_data()`)
3. 查找对应数据库的 DDL 模板
4. 使用 `MyTemplateEngine` 渲染 DDL 模板
5. 如果存在数据(`data.data`),调用 `gen_insert()` 生成插入语句并追加
6. 返回最终 SQL 脚本
---
### 2. `gen_insert(xls: CRUDData) -> str`
根据模型中的数据生成多条 `INSERT INTO ... VALUES ...` 语句。
#### 参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| `xls` | `CRUDData` 实例 | 包含表名和数据行的对象 |
#### 返回值
- 返回拼接后的多条插入语句字符串,每条以分号结尾,换行分隔
#### 处理逻辑
- 提取第一张表的名称:`tbl = xls.summary[0].name`
- 遍历每一行数据:
- 键作为字段名
- 值如果是字符串则加单引号,否则转为字符串
- 组合为标准 `INSERT` 语句
> 示例输出:
```sql
insert into users (id, name, age) values (1, 'Alice', 25);
insert into users (id, name, age) values (2, 'Bob', 30);
```
---
### 3. `model2ddl(folder: str, dbtype: str) -> str`
批量处理一个目录下所有 `.xlsx``.json` 文件,生成统一的 DDL 脚本。
#### 参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| `folder` | `str` | 模型文件所在目录路径 |
| `dbtype` | `str` | 目标数据库类型 |
#### 返回值
- 合并后的完整 DDL 字符串,每个文件前添加注释 `-- 文件路径`
#### 异常处理
- 对每个文件进行 `try...except` 包裹
- 出错时输出异常信息及堆栈跟踪,继续处理其他文件
---
## 模板系统设计
### 模板映射表:`tmpls`
```python
tmpls = {
"sqlserver": sqlserver_ddl_tmpl,
"mysql": mysql_ddl_tmpl,
"oracle": oracle_ddl_tmpl,
"postgresql": postgresql_ddl_tmpl
}
```
> 所有模板均为字符串形式,内部使用占位符(由 `MyTemplateEngine` 解析),例如:
>
> ```sql
> CREATE TABLE {{table_name}} (
> {% for col in columns %}
> {{col.name}} {{col.type}}{% if col.nullable == False %} NOT NULL{% endif %},
> {% endfor %}
> );
> ```
---
## 主程序入口(命令行运行)
### 运行方式
```bash
python your_script.py <dbtype> <folder_or_file>
```
#### 示例
```bash
python model2ddl.py mysql ./models/
```
#### 参数说明
| 参数位置 | 含义 |
|---------|------|
| `sys.argv[1]` | 数据库类型(如 `mysql` |
| `sys.argv[2]` | 模型文件夹路径 |
#### 中文输出兼容性修复
为防止 Windows 控制台因编码问题报错(如 `'gbk' codec can't encode \u200b`),设置 stdout 编码为 UTF-8
```python
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf8')
```
---
## 使用示例
### 输入文件示例(`user.xlsx`
| Field | Type | Null | Default | Comment |
|-----------|-------------|------|---------|---------------|
| id | int | NO | | 主键 |
| username | varchar(32) | NO | | 用户名 |
| email | varchar(64) | YES | NULL | 邮箱地址 |
数据页(可选):
| id | username | email |
|----|----------|------------------|
| 1 | alice | alice@exam.com |
| 2 | bob | bob@exam.com |
---
### 输出示例MySQL
```sql
-- ./models/user.xlsx
CREATE TABLE user (
id INT NOT NULL COMMENT '主键',
username VARCHAR(32) NOT NULL COMMENT '用户名',
email VARCHAR(64) NULL DEFAULT NULL COMMENT '邮箱地址'
);
insert into user (id, username, email) values (1, 'alice', 'alice@exam.com');
insert into user (id, username, email) values (2, 'bob', 'bob@exam.com');
```
---
## 注意事项
1. **文件编码要求**
- JSON 文件必须为 UTF-8 编码
- 推荐所有文件路径不含中文或特殊字符
2. **数据模型格式**
- Excel 文件需符合 `xlsxData` 模块定义的结构规范
- 必须包含字段元信息表(列名、类型、约束等)
- 可选数据表用于生成 `INSERT` 语句
3. **数据库模板扩展**
- 新增数据库支持只需实现新的模板并加入 `tmpls` 映射即可
4. **性能建议**
- 不适用于超大数据集(因全部加载至内存)
- 建议单个模型文件控制在千行以内
---
## 错误处理
| 错误类型 | 表现 | 解决方法 |
|--------|------|--------|
| 文件无法读取 | 输出 `can not read data` | 检查文件格式或权限 |
| 数据为空 | 输出 `not data return from XLSX file` | 检查文件内容是否正确 |
| 数据库类型不支持 | 抛出异常 `%s database not implemented` | 检查拼写或确认已实现该模板 |
| 模板渲染失败 | 抛出模板引擎异常 | 检查模板语法或数据结构匹配性 |
---
## 扩展建议
- 添加配置文件支持不同导出选项(如是否生成 INSERT
- 增加对 SQLite 等更多数据库的支持
- 支持导出到文件而非仅打印到终端
- 提供 GUI 界面或 Web 接口版本
---
## 许可与版权
© 2025 Your Company. All rights reserved.
开源许可证MIT如有
---
📌 **提示**:此工具适用于开发阶段快速搭建数据库 schema 和测试数据,生产环境请结合审核流程使用。