# 技术文档: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 ``` #### 示例 ```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 和测试数据,生产环境请结合审核流程使用。