Python 如何导出 MySQL 数据库字段信息
Python 如何导出 MySQL 数据库字段信息
本篇博文主要是为了说明,利用 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()
原理解析
information_schema 数据库
大家在安装或使用 MySQL 时,会发现除了自己安装的数据库以外,还有一个 information_schema
数据库,information_schema
数据库是 MySQL 自带的,它提供了访问数据库元数据的方式
什么是元数据呢?元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。有些时候用于表述该信息的其他术语包括"数据词典"和"系统目录"
在数据库information_schema
中,有名为 COLUMNS
一张表,这张表里面详细记录了整个数据库中所有列以及每个列的信息,通过 pymysql
模块读取这个表的数据,就可以获取我们目标数据库字段信息
information_schema.columns 表字段介绍
一些常用的字段,已标出
字段 | 含义 |
---|---|
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 |