用 Python 实现 PowerDesigner 数据模型文件的处理

简述

目前在银行研发中心做项目管理工作。我们单位的项目经理从需求、设计、编码到测试以及上线,都要有很大程度的参与。没有工具支持,很多事根本忙不过来、或者没法在有限的时间里保证项目质量。
大概半年前开始接触PYTHON,多多少少写了一些能与项目结合使用的小工具。
从自动化交易接口生成工具,到一些适合我们项目使用的测试工具。
因为项目性质,我手头大部分活儿都是C平台上开发的,我自己也是对C比较熟。 使用PYTHON之后,感觉大好,比起用C实现,一些想法能以快得多的速度用python得以落实或验证,PDMHandler是这些小程序中的一个。

目前此代码托管在GitHub上:

  • 项目主页:https://github.com/petjiang/PDMHandler
  • 源码地址:[email protected]:petjiang/PDMHandler.git

编写背景

  • 我们项目常用PowerDesigner做项目的数据建模管理。
  • 银行对运行中的系统管理是比较严格的,若部署产生问题,可能波及到客户关系、舆情、账务等,风险不小,所以对项目组的要求也十分严苛。
  • 银行系统由于可靠性要求高,所以技术上不会用到最前延的。但业务需求通常较为复杂、而且变化快,数据模型变化相应也就频繁。

目的

我们常见的使用场景,就是修改PowerDesigner模型文件(.pdm),转成SQL,在开发环境上变更数据库实例、业务代码开发。

大量并发需求来时,pdm常被改乱,时间一长pdm与数据库实例的一致性就不能得到保证了。一些较大型的系统几百上千张表,靠人工核对一致性是很苦的体力活儿。

PDMHandler实现的API可以解决这个过程中的SQL生成、PDM与数据库实例的比对、在unix环境下查看pdm数据字典等功能。

实现原理

其实,实现原理还是比较简单的。

只需要突破一个关键点:

PowerDesigner的模型文件(.pdm文件)实际上是一个标准的XML数据文件
没想到吧?:)

一但了解了这一点,实现对.pdm文件的解析就变成了对xml文件的处理。

剩下的事就是:

(1)选用合适的python的xml库 (注:PDMHandler采用了xml.dom.minidom)
(2)分析.pdm文件的详细结构
(3)定义PDMHandler工具类的API接口,实现对.pdm的操作、解析

附注:PDM文件结构简析

所有的"包、表定义、表字段定义、索引、索引字段定义等“全都定义在.pdm文件的这个路径下(以类文件系统路径方式表示):

shell/Model/o:RootObject/c:Children/o:Model

比如(包 - o:Package)定义:
注意:包定义是可嵌套的,/c:Packages/o:Package可反复嵌套;另外o:Model本身也可以看作一个包

shell/Model/o:RootObject/c:Children/o:Model/c:Packages/o:Package ...

再如(表 - o:Table)定义:

shell/Model/o:RootObject/c:Children/o:Model/c:Packages/o:Package/c:Tables/o:Table ...

其它PDM元素的位置不再冗述,请见代码PDMHandler.py
以下是Github中此项目的README.md文件,直接贴一份过来供参考 :)
欢迎fork/clone此项目,提出建议
项目主页:https://github.com/petjiang/PDMHandler
源码地址:[email protected]:petjiang/PDMHandler.git

PDMHandler

A tool class to handle sybase PowerDesigner datafile(.pdm).
Currently, it is able to handle PhysicalDiagram in .pdm.

Source Code Intro.

PDMHandler.py

The class implementation of PDMHandler.
use following command to see help docs (sorry that I type it in Chinese):

shell$ echo "import PDMHandler; help(PDMHandler);"|python

TEST PDM files

PowerDesigner model file (.pdm) is prepared in [repodir]/src/testpdm
use these as input argument for testing the example1.py
* NOTICE: (.pdm) files come from PowerDesigner15 directory [Sybase\PowerDesigner 15\Examples]

example1.py

  • It is a usecase of PDMHandler class, read it as a reference code.
  • example1.py shows 5 levels of pdm file -- Package/Table/Column/Index/IndexColumn
  • each level has their own attributes which are defined in PDMHandler class :
pythonPKG_ATTR_LIST=["Name","Code","CreationDate","Creator","ModificationDate","Modifier"]
TBL_ATTR_LIST=["Name","Code","CreationDate","Creator","ModificationDate","Modifier", "PhysicalOptions"]
COL_ATTR_LIST=["Name","Code","CreationDate","Creator","ModificationDate","Modifier", "DataType","Length","Column.Mandatory","Comment"]
IDX_ATTR_LIST=["Name","Code","CreationDate","Creator","ModificationDate","Modifier", "PhysicalOptions","Unique"]
IDXCOL_ATTR_LIST=["CreationDate","Creator","ModificationDate","Modifier"]

By running :

shell$ python example1.py testpdm/Consol.pdm

shows the output to standout :

shell P: Duplicated Database DUPLICATED_DATABASE lpommier
  T: Duplicated Account DUPLICATED_ACCOUNT vaudino
   T-PATH: /Model/o:RootObject/c:Children/o:Model/c:Tables/o:Table
   C: Email EMAIL char(256) 256 1
   C: Name NAME char(256) 256
   C: URL URL char(256) 256
   I: ACCOUNT_PK ACCOUNT_PK 1
    IC: EMAIL
  T: Duplicated Auteurs DUPLICATED_AUTEURS vaudino
   T-PATH: /Model/o:RootObject/c:Children/o:Model/c:Tables/o:Table
   C: Email EMAIL char(256) 256 1
   C: Title TITLE char(256) 256 1
   I: AUTEURS_PK AUTEURS_PK 1
    IC: EMAIL
    IC: TITLE
   I: Publication_FK PUBLICATION_FK
    IC: EMAIL
   I: Authors_FK AUTHORS_FK
    IC: TITLE
  T: Duplicated Publication DUPLICATED_PUBLICATION vaudino
   T-PATH: /Model/o:RootObject/c:Children/o:Model/c:Tables/o:Table
   C: Title TITLE char(256) 256 1
   C: Email EMAIL char(256) 256 1
   C: Pub_Title PUB_TITLE char(256) 256
   C: Summary SUMMARY long varchar
   C: Keywords KEYWORDS char(256) 256
   I: PUBLICATION_PK PUBLICATION_PK 1
    IC: TITLE
   I: PUBLISHER_FK PUBLISHER_FK
    IC: EMAIL
   I: REFERENCES_FK REFERENCES_FK
    IC: PUB_TITLE

Why I write it ?

Yes,it is just a tiny code for fun.

But I hope more features will be added in it, and it will be useful to solve some headachy problem. Just like :

  • compare the online database instance with PDM file.
  • autogen SQL schema from PDM file (PowerDesigner's auto-gen setting sucks)
  • autogen ORM fro PDM file (seems awesome?!,support embed c,SQLAlchemy..)

你可能感兴趣的:(用 Python 实现 PowerDesigner 数据模型文件的处理)