[转载]我的python工具-代码生成器 – 编码人生 – 博客园.
做企业MIS系统,最烦人的就是建立实体文件,如果使用ORM多数还要建立映射文件,字母稍有不慎拼写错误组件就加载异常,搞的心浮气躁, 于是自然而然想起写一个代码生成工具,虽然业界CodeSmith等成熟工具早已如雷贯耳,但自己动手量体裁衣,用着也舒服,心里也踏实,早些年也曾使用 C#和Groovy分别写过类似的代码,用于不同的项目,今天又想用python实现一个,目的只是想给刚入门或尚未入门的小朋友(新手)一些建议,代码 也是练出来的,多写代码,多总结,多练习,尤其学习一门新的语言时,根据需要做一些实用的工具,按照自己的思路在设计和实现过程中,会遇到很多问题,当你 解决这些问题后,你也很快掌握了该门语言,何乐而不为呢?
闲话不多讲,这就来说说用python实现一个简单的代码生成工具的思路
步骤1.连接数据库
步骤2.查询数据库系统表,获取数据库表及字段元数据信息,如字段名,类型,长度,是否主键,是否可空等信息
步骤3.加载模板信息,根据命名规则,输出实体类、业务类、映射文件等字符串信息
步骤4.输出结果,保存到文件中
1.使用pymsSQL连接数据库:
步骤2.查询数据库系统表,获取数据库表及字段元数据信息,如字段名,类型,长度,是否主键,是否可空等信息
2 systypes.name AS Col_type, syscolumns.length AS Col_len,
3 ISNULL(sys.extended_properties.[value], syscolumns.name) AS Col_memo,
4 CASE WHEN Syscolumns.Name IN
5 (SELECT A.Name
6 FROM Syscolumns A INNER JOIN
7 Sysobjects B ON A.Id = B.Id AND B.Xtype = ‘U‘ AND
8 B.Name <> ‘Dtproperties‘
9 WHERE EXISTS
10 (SELECT 1
11 FROM Sysobjects
12 WHERE Xtype = ‘Pk‘ AND Name IN
13 (SELECT Name
14 FROM Sysindexes
15 WHERE Indid IN
16 (SELECT Indid
17 FROM Sysindexkeys
18 WHERE Id = A.Id AND Colid = A.Colid))) AND
19 B.Name = Sysobjects.Name) THEN 1 ELSE 0 END AS Is_key,
20 Syscolumns.isnullable as IsNullable
21 FROM sys.extended_properties RIGHT OUTER JOIN
22 sysobjects INNER JOIN
23 syscolumns ON sysobjects.id = syscolumns.id INNER JOIN
24 systypes ON syscolumns.xtype = systypes.xtype ON
25 sys.extended_properties.major_id = syscolumns.id AND
26 sys.extended_properties.minor_id = syscolumns.colid
27 WHERE (sysobjects.xtype = ‘U‘ OR
28 sysobjects.xtype = ‘V‘) AND (systypes.name <> ‘Sysname‘) AND
29 (sysobjects.name LIKE ‘%‘)
30 ORDER BY sysobjects.name, syscolumns.colid“””
执行1中的cur.execute(sql); result = cur.fetchall();获取执行上边的sql获取数据库表定义的元数据信息,有心的同学,请自行copy上述sql,在SQL Server 查询窗体里边执行即可看到结果,无需多说.
步骤3.加载模板信息,根据命名规则,输出实体类、业务类、映射文件等字符串信息
通过导入python模块string中的Template定义模板信息如:
/***************************************************
# ${ClassName}.cs
# Comment:
#
# Current Version: V1.0
# Author:
#
# History List:
# V1.0 Created by CodeBuilder@${Datetime}
#******************************************************************************/
using System;
using System.Text;
using Higo.Business namespace ${NameSpace}.Entities
{
[Serializable]
public class ${ClassName}:BaseEntity
{
public ${ClassName}()
{
${Init}
}
${Property}
}
}
根据从数据库中获取到的表结构信息,生成模板中的变量${NameSpace}, ${ClassName}等上下文信息,调用Template.safe_substitute(context),进行变量的替换,并输出替换后的字符 串,此处数据库字段名称到应用程序代码中的类名称需要事先约定好命名规则,如:数据库表明为T_SYS_CODE_DATA,对应实体类名称为 SysCodeData,另外数据表T_SYS_CODE_DATA中的某一列,如F_CODE_NAME,类型为nvarchar(200),对应应用 程序中属性的定义为:public string CodeName {get;set;}, 除命名规则外,还需要一张数据库类型对应应用程序类型映射表,可以定义一个Python全局字典变量,如:
2 “int“:“int“,
3 “text“:“string“,
4 “bigint“:“Int64“,
5 “binary“:“byte[]“,
6 “char“:“string“,
7 “datetime“:“DateTime“,
8 “decimal“:“decimal“,
9 “float“:“double“,
10 “image“:“byte[]“,
11 “money“:“decimal“,
12 “nchar“:“string“,
13 “ntext“:“string“,
14 “numeric“:“float“,
15 “nvarchar“:“string“,
16 “real“:“Single“,
17 “smalldatetime“:“DateTime“,
18 “smallint“:“Int16“,
19 “smallmoney“:“decimal“,
20 “timestamp“:“DateTime“,
21 “tinyint“:“byte“,
22 “uniqueidentifier“:“Guid“,
23 “varbinary“:“byte[]“,
24 “varchar“:“string“,
25 “variant“:“object“,
26 “bit“:“bool“}
通过dbmap[“nvarchar”]获取到的对应类型为string
步骤4.输出结果,保存到文件中
2 if not os.path.exists(filePath):
3 temp = os.path.dirname(filePath)
4 if not os.path.exists(temp):
5 os.makedirs(temp)
6 else:
7 os.remove(filePath)
8 f = open(filePath,‘w‘)
9 f.write(buf)
10 f.close()
ok,大功告成,思路很简单,但在用python代码实现的过程中,熟悉了一下python的数据库操作以及字符串模板替换、列表表达式过滤等常规用法。
源码在这里:/Files/wdong/CodeBuilder.rar,同时也希望得到您的回复和指教,谢谢