1.前言
近期需要做达梦数据库到MySQL数据的迁移,发现建表脚本基本没问题,但是表和列的注释问题很大,需要写代码来处理生成。
2.详细内容
达梦数据库的表和字段的备注如下:
COMMENT ON TABLE SYS_USER IS '用户表'; -- 表备注
COMMENT ON COLUMN SYS_USER.NAME IS '用户名称'; -- 字段备注
MySQL的表和字段的备注如下:
ALTER TABLE SYS_USER COMMENT = '用户表'; -- 表备注
ALTER TABLE SYS_USER MODIFY COLUMN NAME varchar(32) COMMENT '用户名称'; -- 字段备注
3.python脚本实现
准备原达梦的备注脚本,例如下面:
COMMENT ON TABLE SYS_USER IS '用户表'; -- 表备注
COMMENT ON COLUMN SYS_USER.NAME IS '用户名称'; -- 字段备注
-- 可以很多,这里只是个例子
脚本代码:
import pymysql
from dbutils.pooled_db import PooledDB
POOL = PooledDB(
creator=pymysql, # 使用连接数据库的模块
maxconnections=10, #连接池允许的最大连接数,0和none表示不限制连接数
mincached=2, #初始化时,连接池中至少创建的空闲的连接,0表示不创建
maxcached=5, #连接池中最多闲置的连接,0和None不限制
blocking=True, #连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
setsession=[], #开始会话前执行的命令列表。如:{"set datestyle to...", "set time zone..."}
ping=0,
host="192.168.102.11", port=3306, user='root', passwd='123456', db='test',charset='utf8mb4'
)
tableInfoMap = {}
class TableInfo:
def __init__(self, Field, Type, Collation, Null, Key, Default, Extra, Privileges, Comment):
self.Field = Field
self.Type = Type
self.Collation = Collation
self.Null = Null
self.Key = Key
self.Default = Default
self.Privileges = Privileges
self.Comment = Comment
self.Extra = Extra
def get_column_type(curson, table, columnName):
table_infos = tableInfoMap.get(table, None)
if table_infos is None:
curson.execute(f"SHOW FULL COLUMNS FROM {table}")
rows = curson.fetchall()
table_infos = [TableInfo(*row) for row in rows]
tableInfoMap[table] = table_infos
for tableInfo in table_infos:
if tableInfo.Field.lower() == columnName.lower():
return tableInfo.Type
raise Exception(f"No such column named {columnName} in table {table}")
if __name__ == '__main__':
conn = POOL.connection()
curson = conn.cursor()
table_comments = []
column_comments = []
# 读取sourceComment.sql 就是达梦的表和字段的备注脚本文件
file_path = "./sourceComment.sql"
# 打开文件并逐行读取
with open(file_path, 'r', encoding='utf-8') as file:
for line in file:
if len(line) == 0 or line.strip() == '':
continue
if line.startswith('COMMENT ON TABLE'):
table_comments.append(line.replace("COMMENT ON ", "ALTER ")
.replace(" IS ", " COMMENT = "))
elif line.startswith('COMMENT ON COLUMN '):
startTableIndex = len('COMMENT ON COLUMN ')
endTableIndex = line.index(' IS ')
tableAndColumn = line[startTableIndex:endTableIndex]
commentInfo = line[endTableIndex + 3:]
tableAndColumnArray = tableAndColumn.split(".")
table = tableAndColumnArray[0]
column = tableAndColumnArray[1]
columnType = get_column_type(curson, table, column)
column_comments.append(f"ALTER TABLE {table} MODIFY COLUMN {column} {columnType} COMMENT {commentInfo}")
# 执行注释sql
for table_comment in table_comments:
curson.execute(table_comment)
for column_comment in column_comments:
curson.execute(column_comment)
conn.commit()
curson.close()
conn.close() # 这个就只是放回连接不是关闭