项目中的文档经常有展示ER图的要求,可以采用PD等工具对数据库进行逆向工程生成。但是这些工具一般只能从数据库获取英文的字段名,对于业务信息的展示并不如中文名称的含义直观。
在作者所在的单位有自己的开发平台,及低代码工具。业务模型是用XML来定义描述的,包括了数据库结构和页面元素。对于简单的字典形业务,进行模型配置后即可以通过低代码引擎自动实现数据库表的创建和前端HTML页面的生成,十分方便。对于复杂的业务,需要在视图层进行已定义接口的二次开发来实现。整个过程中并没有采用任何CDM设计工具。所以从模型生成EP图就是一个需求,对于小一些的项目,可以用工具在画一个对应的。对于几百个业务对象的项目,再次画就是一个负担而且容易出现属性不对应的情况。
所以考虑有没有通过程序生成ER图的工具,erdantic就是这样一个库,可以把Python的类生成对应的ER图。
这里要明确,我们只需要把类之间的关系定义出来就行。并不需要用Python再实现一下现有的系统。我们的业务模型在Asp.net上用XML描述,在springboot上用Json描述,只需要把这些模型里的定义转换成Python类即可。
注意这里就用到graphviz默认的安装路径了
python -m pip install --global-option=build_ext --global-option="-IC:Program FilesGraphvizinclude" --global-option="-LC:Program FilesGraphvizlib" pygraphviz
pip install erdantic
直接安装的版本会有中文乱码,需要安装开发版
要修改的文件为erd.py
修改成微软雅黑字体
先对模型进行一些处理,将业务模型中相对独立的类型都放到前面 (Python对类引用时先后关系会有要求)然后分析类型间的依赖关系,这里的原理是拓扑排序。本人的测试代码用C#编写。并用到了一个库 Topological-sorting-in-Csharp
static void GeneratePythonContent(IList<_DemClass> cls, _DemModel model)
{
string memberT = " MemberName : MemberType ";
string dataTypeT = @"
class ClassNameEn (BaseModel):
MemberNames
";
StringBuilder sb = new StringBuilder();
foreach (var classItem in cls)
{
List memberResult = new List();
var commonMembers = classItem.GetCommonMembers();
foreach (var commonMember in commonMembers)
{
memberResult.Add(memberT.Replace(" MemberName ", name).Replace(" MemberType ", "int"));
}
var dependencyMembers = classItem.Members.Except(commonMembers);
foreach (var member in dependencyMembers)
{
if (member.IsMultiInstance)
{
memberResult.Add(memberT.Replace(" MemberName ", member.DisplayName).Replace(" MemberType ", "List[" + member.DataTypeName + "]"));
}
else
{
memberResult.Add(memberT.Replace(" MemberName ", member.DisplayName).Replace(" MemberType ", member.DataTypeName));
}
}
string dataTypeResult = dataTypeT.Replace(" ClassNameEn ", classItem.Name).Replace(" MemberNames ", string.Join("
", memberResult));
sb.AppendLine(dataTypeResult);
}
string cc = sb.ToString();
}
最终生成的Python类格式为:
#!/usr/bin/python3
# -*- coding:utf-8 -*-
import erdantic as erd
from erdantic.examples.pydantic import Party
from datetime import datetime
from typing import List
from pydantic import BaseModel
class ChannelType(BaseModel):
主键: int
name: str
#其他的类型略...
class VideoManagement(BaseModel):
主键: int
名称: str
提交时间: datetime
编号: str
备注: str
文件: List[str]
ProjectNode: str
提交人: dps_User
## 指定一个基础类
VideoManagement.update_forward_refs(**locals())
diagram = erd.create(VideoManagement)
diagram.draw("diagram.png")
页面更新:2024-03-03
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号