最近在搞一个项目所以下班有点晚,坐在地铁上习惯性的拿出Ipad刷一会研究生课程。突然手机响了,一看原来是组织语音会议, 讨论客户需要系统的er图,有400多张要求晚上搞定明天发出去。由于我们没设置外键约束,因此用powerdesigner无法把表之间的关联关系展示出来。由于表数量多、时间紧急,大家讨论说晚上可能时间来不及,建议和用户沟通延后一下。
然后我沉默了一会,突然灵感闪现,说把所有的表结构sql给我,到家后看看(没有当场给出答复,毕竟谋定而后动!)
分析sql提取特征
下面给出sql demo
create table `term_relationships`
(
`object_id` bigint(20) unsigned not null default 0 comment '对应文章ID/链接ID',
`term_taxonomy_id` bigint(20) unsigned not null default 0 comment '对应分类方法ID',
`term_order` int(11) not null default 0 comment '排序',
primary key (`object_id`, `term_taxonomy_id`)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
alter table term_relationships comment '文章属性关系表';
/*==============================================================*/
/* Table: term_taxonomy */
/*==============================================================*/
create table `term_taxonomy`
(
`term_taxonomy_id` bigint(20) unsigned not null auto_increment comment 'ID',
`description` longtext comment '说明',
`parent` bigint(20) unsigned not null default 0 comment '属父分类方法ID',
`count` bigint(20) not null default 0 comment '文章数统计',
`site_id` bigint(20) comment '站点id',
primary key (`term_taxonomy_id`)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
alter table term_taxonomy comment '栏目';
经过分析,大部分表外键的命名方式是:被引用表的表名+下划线+id
既然有规律,而且领导意思是准确度可以没那么高,那我就用Python写一个文本解析工具,自动生成外键sql然后再逆向生成er图。
其中绿色的是key
上代码
import math
import re
primayKeyTableMap = {
}
class Stack(object):
def __init__(self):
self.stack = []
def push(self, data):
"""
进栈函数
"""
self.stack.append(data)
def pop(self):
"""
出栈函数,
"""
return self.stack.pop()
def gettop(self):
"""
取栈顶
"""
return self.stack[-1]
def __len__(self):
return len(self.stack)
stack1 = Stack()
list1 = []
def findTableAndPrimayKey():
p1 = re.compile(r'[`](.*?)[`]', re.S)
with open('D:/1.sql','r', encoding='utf-8') as infile:
for line in infile:
if 'CREATE TABLE' in line :
tableName = re.findall(p1, line)[0]
if len(stack1) != 0 :
tempTableKey = stack1.pop()
tempTableName = stack1.pop()
if len(tempTableKey) > 2:
# print(tempTableKey)
primayKeyTableMap[tempTableKey] = [tempTableName,tempTableKey]
else:
# print(tempTableName+'_'+tempTableKey)
primayKeyTableMap[removePre(tempTableName)+'_'+tempTableKey] = [tempTableName,tempTableKey]
stack1.push(tableName)
if 'PRIMARY KEY' in line :
keyName = re.findall(p1, line)
stack1.push(keyName[0])
def addForeignKey():
tableName = ''
keyName = ''
p1 = re.compile(r'[`](.*?)[`]', re.S)
with open('D:/1.sql','r', encoding='utf-8') as infile:
for line in infile:
if 'CREATE TABLE' in line :
tableName = re.findall(p1, line)[0]
# stack1.push(tableName)
elif '_USER_ID' in line or '_user_id' in line:
foreignCloumn = re.findall(p1, line)
sql = 'alter table '+tableName+' add foreign key('+foreignCloumn[0]+') references Z_IS_USER(USER_ID) on delete cascade on update cascade; '
print(sql)
else :
foreignCloumn = re.findall(p1, line)
if len(foreignCloumn) > 0 and foreignCloumn[0] in primayKeyTableMap and primayKeyTableMap[foreignCloumn[0]][0]!=tableName :
sql = 'alter table '+tableName+' add foreign key('+foreignCloumn[0]+') references '+primayKeyTableMap[foreignCloumn[0]][0]+'('+primayKeyTableMap[foreignCloumn[0]][1]+') on delete cascade on update cascade; '
print(sql)
def removePre(tableName):
return tableName.replace("IS_", "").replace("is_", "").replace("P_", '').replace('QRTZ_','').replace('Z_IS_','').replace('MS_','').replace('acl_','')
def main():
findTableAndPrimayKey()
# print(primayKeyTableMap)
addForeignKey()
main()
利用程序,2小时我完成了工作,避免了繁琐的画图和加班,哈哈!
最后祝大家1024快乐!