本篇博文主要是为了说明,利用 Python 如何将 MySQL 数据库中数据库名称
,数据表名称
、字段
等相关信息予以自动化导出,并简要阐明其原理
2B 业务场景,项目验收材料中要求,要有关于数据库字段名称
,字段类型
,最大长度
以及字段注释
的说明文档,在动辄几十个数据表的数据库中,如果纯手写,那绝对会怀疑人生。人生苦短,我用 Python,于是写了一个 Python 脚本,自动化导出成 MarkDown
文档
from datetime import datetime
import pymysql
TITLE_HEAD = """# {system_name}数据库设计文档
**文档版本:**1.0.0.0
**发布时间:**{now}
**文档描述:**
? 本文档是{system_name}数据库设计文档,数据库是 `Mysql`,以下将主要说明:`字段名称`、`字段类型`、`字段长度`、以及`字段解释`。
"""
TABLE_HEADER = """## {num}. {table_name}
| 序号 | 字段名称 | 数据类型 | 长度 | 解释说明 |
| :--: | :---------: | :------: | :--: | :--------: |"""
TABLE_BODY = """
| {index} | {field} | {field_type} | {field_leght} | {field_explain} |"""
TABLE_TAIL = """
\n
\n
"""
class ExportDatabaseField():
def __init__(self, system_name: str, database_params: dict):
self._system_name = system_name
self._params = database_params
self._database_connect = None
self._cursor = None
self._connect_database_server()
def _connect_database_server(self) -> None:
self._database_connect = pymysql.connect(**self._params)
self._cursor = self._database_connect.cursor()
def close_connect(self) -> None:
self._cursor.close()
self._database_connect.close()
self._cursor = None
self._database_connect = None
def _verify_connection(self) -> None:
ret = False
try:
self._database_connect.ping()
ret = True
except Exception as err:
self.close_connect()
self._connect_database_server()
return ret
def get_table_names(self, db_name: str) -> tuple:
sql_command = "select distinct(table_name) from INFORMATION_SCHEMA.Columns where table_schema=‘{0}‘".format(db_name)
self._cursor.execute(sql_command)
query_data = self._cursor.fetchall()
return [item[0] for item in query_data]
def get_column_infors(self, table_name: str, db_name: str) -> tuple:
sql_command = "select column_name, data_type, character_maximum_length, column_comment from INFORMATION_SCHEMA.Columns where table_name=‘{0}‘ and table_schema=‘{1}‘".format(table_name, db_name)
self._cursor.execute(sql_command)
query_data = self._cursor.fetchall()
return query_data
def save_into_file(self, file_name: str) -> object:
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
system_name = self._system_name
file_name = "{0}.md".format(file_name)
database_name = self._params["database"]
with open(file_name, "w", encoding="utf8") as file_obj:
file_obj.write(TITLE_HEAD.format(system_name=system_name, now=now))
table_names = self.get_table_names(database_name)
for num, table in enumerate(table_names, start=1):
table_infos = self.get_column_infors(table, database_name)
file_obj.write(TABLE_HEADER.format(num=num, table_name=table))
for index, info in enumerate(table_infos, start=1):
content = TABLE_BODY.format(index=index, field=info[0], field_type=info[1], field_leght=info[2] if info[2] else "", field_explain=info[3])
file_obj.write(content)
file_obj.write(TABLE_TAIL)
def main():
database_confis = {"database": "database_name",
"host": "127.0.0.1",
"port": 3306,
"user": "root",
"password": "123456",
"charset": "utf8"}
system_name = "测试项目数据库设计文档"
factory = ExportDatabaseField
instance = factory(system_name, database_confis)
file_name = "{0}数据库设计文档".format(system_name)
instance.save_into_file(file_name)
if __name__ == "__main__":
main()
大家在安装或使用 MySQL 时,会发现除了自己安装的数据库以外,还有一个 information_schema
数据库,information_schema
数据库是 MySQL 自带的,它提供了访问数据库元数据的方式
什么是元数据呢?元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。有些时候用于表述该信息的其他术语包括"数据词典"和"系统目录"
在数据库information_schema
中,有名为 COLUMNS
一张表,这张表里面详细记录了整个数据库中所有列以及每个列的信息,通过 pymysql
模块读取这个表的数据,就可以获取我们目标数据库字段信息
一些常用的字段,已标出
字段 | 含义 |
---|---|
table_schema | 数据库名称 |
table_name | 表名 |
column_name |
列名 |
ordinal_position | 列标识号 |
column_default |
列的默认值 |
is_nullable | 列的为空性。如果列允许 null,那么该列返回 yes。否则,返回 no |
data_type |
系统提供的数据类型 |
character_maximum_length |
以字符为单位的最大长度,适于二进制数据、字符数据,或者文本和图像数据。否则,返回 null。有关更多信息,请参见数据类型 |
character_octet_length | 以字节为单位的最大长度,适于二进制数据、字符数据,或者文本和图像数据。否则,返回 nu |
numeric_precision | 近似数字数据、精确数字数据、整型数据或货币数据的精度。否则,返回 null |
numeric_precision_radix | 近似数字数据、精确数字数据、整型数据或货币数据的精度基数。否则,返回 null |
numeric_scale | 近似数字数据、精确数字数据、整数数据或货币数据的小数位数。否则,返回 null |
datetime_precision | datetime 及 sql-92 interval 数据类型的子类型代码。对于其它数据类型,返回 null |
character_set_catalog | 如果列是字符数据或 text 数据类型,那么返回 master,指明字符集所在的数据库。否则,返回 null |
character_set_schema | 如果列是字符数据或 text 数据类型,那么返回 dbo,指明字符集的所有者名称。否则,返回 null |
character_set_name | 如果该列是字符数据或 text 数据类型,那么为字符集返回唯一的名称。否则,返回 null |
collation_catalog | 如果列是字符数据或 text 数据类型,那么返回 master,指明在其中定义排序次序的数据库。否则此列为 null |
collation_schema | 返回 dbo,为字符数据或 text 数据类型指明排序次序的所有者。否则,返回 null |
collation_name | 如果列是字符数据或 text 数据类型,那么为排序次序返回唯一的名称。否则,返回 null。 |
domain_catalog | 如果列是一种用户定义数据类型,那么该列是某个数据库名称,在该数据库名中创建了这种用户定义数据类型。否则,返回 null |
domain_schema | 如果列是一种用户定义数据类型,那么该列是这种用户定义数据类型的创建者。否则,返回 null |
domain_name | 如果列是一种用户定义数据类型,那么该列是这种用户定义数据类型的名称。否则,返回 NULL |
原文:https://www.cnblogs.com/chaosmoor/p/14765348.html