基于python根据Excel生成数据库表结构

引言

拿到新项目后,要根据原型来设计表结构,然鹅表结构写好了,要往数据库里创建表结构,又是个麻烦的事情,所以写下了以下脚本,便于快速生成数据库和表结构。

代码

import openpyxl
import pymysql

global connect, sql_segment, primaryKeyFlag, unionFlag
host = "127.0.0.1"
port = 3306
user = "root"
password = "******"
connect = None
tableExistsSkipIt = True
databaseList = []
workbook = openpyxl.load_workbook(r"F:\Desktop\table.xlsx")  # excel路径
sheet = workbook["Sheet1"]  # Sheet表
column_m = sheet.max_column + 1  # 列数
row_m = sheet.max_row + 1  # 行数
databaseName = ""  # 数据库名
tableName = ""  # 表名
tableDesc = ""  # 表描述
columnName = ""  # 列名
columnDesc = ""  # 列描述
columnType = ""  # 字段类型
primaryKeyFlag = ""  # 主键标识
unionFlag = ""  # 联合唯一标识
notNull = ""  # 非空标识
jmpFlag = False
sql_segment = ""


def init():
    global connect
    connect = pymysql.Connect(host=host, port=port, user=user, password=password)
    cursor = connect.cursor()
    cursor.execute("show databases")
    fetchall = cursor.fetchall()
    for i in fetchall:
        databaseList.append(i[0])


def execute(sql):
    cursor = connect.cursor()
    cursor.execute(sql)


def checkDatabaseExists(databaseName):
    return databaseName in databaseList


def createTable():
    global connect, sql_segment, primaryKeyFlag, unionFlag
    if primaryKeyFlag != "":
        sql_segment += f"PRIMARY KEY({primaryKeyFlag[:-2] if len(primaryKeyFlag) > 3 else primaryKeyFlag[:-1]}),\n"
    if unionFlag != "":
        sql_segment += f"UNIQUE INDEX({unionFlag[:-2]}),\n"

    sql_segment = sql_segment[:-2] + f") COMMENT = '{tableDesc if tableDesc is not None else ''}';"
    print(f"[#] 创建数据表 {tableName}")
    sql_segment = sql_segment.replace("None", "")
    execute(sql_segment)
    unionFlag = ""
    primaryKeyFlag = ""


if __name__ == "__main__":
    sql_segment = f"CREATE TABLE `{databaseName}`.`{tableName}`("
    init()
    for x in range(2, row_m):
        for y in range(1, column_m + 1):
            cell = sheet.cell(x, y)
            if cell.value is not None and y < 4:
                if y == 1:
                    databaseName = cell.value
                elif y == 2:
                    tableName = cell.value
                elif y == 3:
                    tableDesc = cell.value
                jmpFlag = True
            elif y == 4:
                columnName = cell.value
            elif y == 5:
                columnDesc = cell.value
            elif y == 6:
                columnType = cell.value
            elif y == 7:
                if cell.value is not None:
                    primaryKeyFlag += f"""`{columnName}`, """
            elif y == 8:
                if cell.value is not None:
                    unionFlag += f"""`{columnName}`, """
            if jmpFlag:
                if not checkDatabaseExists(databaseName):
                    execute(f"""create database if not exists {databaseName}""")
                    databaseList.append(databaseName)
                    print(f"[#] 创建数据库 {databaseName}")
                sql_segment = f"CREATE TABLE {'if not exists' if tableExistsSkipIt else ''}`{databaseName}`.`{tableName}`(\n"
                jmpFlag = False
        if columnName is not None:
            sql_segment += f"{columnName} {columnType} {'not null ' if notNull else ' '}comment '{columnDesc}',\n"
        if columnName is None:
            createTable()

表模板

image.png
表模板解释:
库名:数据库名称
数据表:表名称
表解释:表的注释
字段名:字段名称
字段解释:字段的备注
数据类型:字段的数据类型,需满足MySQL数据类型规则,严格区分半全角符号
主键标识:所在行是否是主键
联合唯一标识: 所在的表唯一联合标识不为空的时候,他们共同构成唯一索引
非空标识: 目标字段是否允许为空
备注:不参与建表

⚠️注意事项

⚠️ 每个表之间需要间隔一行,颜色随意
⚠️ 主键、唯一和非空,如果手误写错了,需要删除内容,如果里面存在内容即为true
⚠️ 数据类型需要满足MySQL的语法
⚠️ 表格中颜色对最终结果没有影响
⚠️ 是否合并单元格不影响最终结果,但是看起来不太好看了

模板下载

脚本自行复制上面的代码
table.xlsx

通过脚本创建后的效果图(打码)

image.png
image.png

注释完整,开发时候找字段就方便多了。

评论 1

  1. zmx
    未经过完整的测试,仅对少数项目作为模板创建,经测试的表结构创建正常,但不保证满足所有情况,具体情况需要具体分析,也欢迎大家修改。
提交后需要审核才会公开。