:::tip 本章概要 表结构解析引擎的工作原理,从数据库读取表元数据并智能推断字段用途的过程。 ::: # 表结构解析引擎 `src/modules/generator/parser.py` 是代码生成器的解析层,负责从数据库 `information_schema` 读取表元数据,输出标准化的配置字典。 ## 核心类:TableSchemaParser ```python from modules.generator.parser import TableSchemaParser parser = TableSchemaParser("tornado_example") config = parser.parse() ``` ### 构造参数 | 参数 | 说明 | |:----|:----| | `table_name` | 数据库表名,可带前缀(`tornado_example`)或不带前缀(`example`) | 构造时自动处理: - 保存原始表名(用于数据库查询) - 去掉 `tornado_` 前缀(用于生成代码命名) - 初始化排除字段列表(`id` / `create_user` / `create_time` / `update_user` / `update_time` / `is_delete`) ## 解析流程 `parse()` 方法执行 9 步: ``` 1. 获取表信息(TABLE_COMMENT、ENGINE 等) 2. 获取字段列表(排除系统字段) 3. 获取索引信息 4. 清理表名(去掉 tornado_ 前缀) 5. 构建命名(app_name / module_comment / model_class_name) 6. 构建字段配置列表 7. 判断功能标识(has_sort / has_status / has_unique_code) 8. 获取显示字段(优先 name → title → 第一个字符串字段) 9. 组装完整配置字典 ``` ## 智能识别规则 ### 图片字段 字段名包含以下关键词时,`is_image` 标记为 `True`: ``` avatar / cover / logo / image / photo / picture / img / icon / thumbnail / banner ``` 效果: - 前端表单生成图片上传组件 - 列表中显示图片预览 - Service 层自动处理文件迁移和 URL 补全 - 自动设置 `filterable=False`、`searchable=False` ### 富文本字段 `Text` 类型字段且注释包含以下关键词时,`is_rich_text` 标记为 `True`: ``` 内容 / 介绍 / 说明 / 描述 / 详情 / 正文 ``` 效果: - 前端表单生成富文本编辑器 - Service 层自动进行 XSS 清洗 ### 状态字段 字段名包含以下关键词时,`is_status` 标记为 `True`: ``` status / state / is_active / is_enabled / is_deleted ``` 效果: - 自动生成状态切换接口(`/status`) - 前端列表生成状态标签(启用/停用) - `has_status_route=True` ### 排序字段 字段名包含以下关键词时,`is_sort` 标记为 `True`: ``` sort / order / seq / sequence / priority ``` 效果: - 分页查询默认按此字段排序 - `page_order_by` 自动配置 ### 枚举字段 字段注释包含 `数字-文本` 格式(如 `1-正常 2-停用`)时,自动解析为选项列表: ```python # 注释:"案例类型:1-类型1 2-类型2 3-类型3" # 解析结果: choices = [(1, '类型1'), (2, '类型2'), (3, '类型3')] dict_code = 'example_type' ``` 效果: - 前端表单生成下拉选择框 - 列表中显示选项文本而非数字 - 自动设置 `filter_type='精确匹配'` - 生成数据字典编码,用于 `serialize_maps` ### 查询条件 字段满足以下任一条件时,`filterable` 标记为 `True`: 1. 字段名包含关键词:`name` / `title` / `code` / `mobile` / `phone` / `email` / `username` / `type` / `category` / `status` / `dept_id` / `role_id` 等 2. 字段有数据库索引 3. 整数字段且有选项 查询类型判断: - 字符串字段(非编码类)→ `模糊查询`(LIKE) - 编码字段(code/sn/no)→ `精确匹配`(=) - 整数字段 + 有选项 → `精确匹配`(=) - 状态字段 → `精确匹配`(=) ## 字段类型映射 ### 数据库 → SQLAlchemy | 数据库类型 | SQLAlchemy 类型 | |:----|:----| | varchar / char | String | | text / longtext / mediumtext / tinytext | Text | | int / tinyint / smallint / mediumint | Integer | | bigint | BigInteger | | datetime / timestamp | DateTime | | date | Date | | time | Time | | float / double / real | Float | | decimal | Numeric | | boolean / bit | Boolean | | json | JSON | ### SQLAlchemy → Pydantic | SQLAlchemy 类型 | Pydantic 类型 | |:----|:----| | String / Text | str | | Integer / BigInteger | int | | Float / Numeric | float | | Boolean | bool | | DateTime / Date / Time | str | | JSON | str | ### SQLAlchemy → 中文显示 | SQLAlchemy 类型 | 中文 | |:----|:----| | String | 字符串 | | Text | 长文本 | | Integer | 整数 | | BigInteger | 大整数 | | DateTime | 日期时间 | | Float | 浮点数 | | Numeric | 小数 | | Boolean | 布尔值 | ## 输出配置结构 `parse()` 返回的配置字典结构: ```python { "app_name": "example", # 模块名(去前缀小写) "module_comment": "案例", # 模块中文名(表注释去掉"表"字) "model_name": "example", # 模型名 "model_class_name": "Example", # 模型类名(帕斯卡命名) "route_prefix": "example", # 路由前缀 "permission_prefix": "sys:example", # 权限前缀 "primary_key": "id", # 主键字段 "display_field": "name", # 显示字段 "display_field_camel": "name", # 显示字段驼峰 "table_name": "example", # 表名(去前缀) "has_sort": True, # 有排序字段 "has_status": True, # 有状态字段 "has_unique_code": True, # 有唯一编码字段 "has_export": False, # 有导出功能 "has_image_field": False, # 有图片字段 "has_rich_text_field": True, # 有富文本字段 "fields": [ # 字段配置列表 { "name": "name", "camel_name": "name", "comment": "案例名称", "py_comment": "案例名称", "db_type": "String", "db_args": "100", "form_type": "str", "type_display": "字符串", "max_length": 100, "nullable": False, "required": True, "is_unique": False, "db_index": False, "default": None, "default_repr": None, "in_form": True, "in_list": True, "filterable": True, "filter_type": "模糊查询", "editable": True, "searchable": True, "is_image": False, "is_rich_text": False, "is_status": False, "is_sort": False, "choices": None, "min_value": None, "max_value": None, }, # ... 更多字段 ] } ``` ## 与 code_generator.py 的关系 ``` parser.py code_generator.py ┌─────────────────────┐ ┌─────────────────────┐ │ TableSchemaParser │ │ CodeGenerator │ │ │ │ │ │ information_schema │ config │ Jinja2 模板渲染 │ │ ─────────────────> │ ───────> │ ─────────────────> │ │ 解析表结构 │ 字典 │ 生成文件 │ └─────────────────────┘ └─────────────────────┘ ``` `parser.py` 负责"读",`code_generator.py` 负责"写",通过配置字典解耦。 ## 总结 表结构解析引擎从数据库读取表和字段的元信息(类型、长度、注释、索引等),智能推断字段用途(是否可搜索、是否在列表显示、对应字典编码等),为代码生成器提供结构化的表描述数据。