This commit is contained in:
yumoqing 2025-11-07 17:20:30 +08:00
parent 01a56d4b56
commit da8277b3b3
4 changed files with 209 additions and 3 deletions

43
docs/dbtable.md Normal file
View File

@ -0,0 +1,43 @@
# 数据库表定义规范
数据库表用一个json格式文件或数据来定义具体规范如下
{
"name"
"title"
"primary"
"catelog" # 可选项entity relation dimession indication
"fields":[ # 字段
{
"name"
"title"
"type" #可选项有str char short long llong date time timestamp float double ddouble decimal text
"length"
"dec"
"nullable" # 可选项yes no
"default"
"comments" # 注释
}
]
"indexes":[
{
"name" # 每个索引一个idxname不能重复一个表中
"idxtype" # unique or index
"idxfields" # 字段名或字段名数组[f1,f1]
}
]
“codes":[ # 如果一个字段数据可以从其他表中获得,可以通过下面的模式定义选择输入逻辑
{
"field" # 字段的名字
"table" # 数据来源表
"valuefield" # 数据来源表值字段
"textfield" # 数据来源表显示字段
"cond" # 检索条件
}
]
]
说明:
id字段全部使用str 32类型
字典中的length如果type是str char float double ddouble decimal中的一个则必为>0的数字
字典中的dec: 如果type是float double ddouble decimal中的一个则必须是>0的数字

View File

@ -17,4 +17,5 @@ install_requires =
console_scripts = console_scripts =
xls2ddl = xls2ddl.xls2ddl:main xls2ddl = xls2ddl.xls2ddl:main
xls2ui = xls2ddl.xls2ui:main xls2ui = xls2ddl.xls2ui:main
json2xlsx = xls2ddl.json2xlsx

162
xls2ddl/json2xlsx.py Normal file
View File

@ -0,0 +1,162 @@
import json
import os
from openpyxl import Workbook
def save_table_json_to_xlsx(table_json, output_dir="."):
"""
将数据库表定义的 JSON 数据写入 .xlsx 文件
:param table_json: 字典符合数据库表定义规范的 JSON 数据
:param output_dir: 输出目录
"""
# 提取表名作为文件名
table_name = table_json.get("name")
if not table_name:
raise ValueError("JSON 中缺少 'name' 字段")
filename = f"{table_name}.xlsx"
filepath = os.path.join(output_dir, filename)
# 创建工作簿
wb = Workbook()
# --- summary sheet ---
ws_summary = wb.active
ws_summary.title = "summary"
summary_headers = ["name", "title", "primary", "catelog"]
ws_summary.append(summary_headers)
ws_summary.append([
table_json.get("name", ""),
table_json.get("title", ""),
table_json.get("primary", ""),
table_json.get("catelog", "")
])
# --- fields sheet ---
ws_fields = wb.create_sheet("fields")
field_headers = ["name", "title", "type", "length", "dec", "nullable", "default", "comments"]
ws_fields.append(field_headers)
for field in table_json.get("fields", []):
row = [
field.get("name", ""),
field.get("title", ""),
field.get("type", ""),
field.get("length", ""),
field.get("dec", ""),
field.get("nullable", ""),
field.get("default", ""),
field.get("comments", "")
]
ws_fields.append(row)
# --- indexes sheet ---
ws_indexes = wb.create_sheet("indexes")
index_headers = ["name", "idxtype", "idxfields"]
ws_indexes.append(index_headers)
for idx in table_json.get("indexes", []):
idxfields = idx.get("idxfields")
# 如果 idxfields 是列表,转成字符串形式 f1,f2否则保持原样
idxfields_str = ",".join(idxfields) if isinstance(idxfields, list) else str(idxfields)
ws_indexes.append([
idx.get("name", ""),
idx.get("idxtype", ""),
idxfields_str
])
# --- codes sheet ---
ws_codes = wb.create_sheet("codes")
code_headers = ["field", "table", "valuefield", "textfield", "cond"]
ws_codes.append(code_headers)
for code in table_json.get("codes", []):
ws_codes.append([
code.get("field", ""),
code.get("table", ""),
code.get("valuefield", ""),
code.get("textfield", ""),
code.get("cond", "")
])
# 保存文件
wb.save(filepath)
print(f"✅ 已生成文件: {filepath}")
# ======================
# 使用示例
# ======================
if __name__ == "__main__":
import os, sys
import codecs
import json
if len(sys.argv) < 2:
print(f'{sys.argv[0] dbtable_json_file ...')
sys.exit(1)
for a in sys.argv[1:]:
with open(a, 'r', encoding='utf-8') as file:
content = file.read()
data = json.loads(content)
if not isinstance(data, list):
data = [data]
for d in data:
save_table_json_to_xlsx(d)
"""
# 示例 JSON 数据
sample_json = {
"name": "user_info",
"title": "用户信息表",
"primary": "id",
"catelog": "entity",
"fields": [
{
"name": "id",
"title": "用户ID",
"type": "str",
"length": 32,
"nullable": "no",
"comments": "主键32位字符串"
},
{
"name": "age",
"title": "年龄",
"type": "short",
"nullable": "yes",
"default": 0,
"comments": "用户年龄"
},
{
"name": "salary",
"title": "月薪",
"type": "decimal",
"length": 10,
"dec": 2,
"nullable": "yes",
"default": "0.00",
"comments": "精确到分"
}
],
"indexes": [
{
"name": "idx_user_age",
"idxtype": "index",
"idxfields": ["age"]
},
{
"name": "idx_user_salary",
"idxtype": "unique",
"idxfields": ["id", "salary"]
}
],
"codes": [
{
"field": "dept_id",
"table": "department",
"valuefield": "id",
"textfield": "name",
"cond": "status=1"
}
]
}
# 调用函数生成 xlsx
save_table_json_to_xlsx(sample_json)
"""

View File

@ -164,7 +164,7 @@ class CRUDData(XLSXData):
return False return False
if 'fields' not in names: if 'fields' not in names:
return False return False
if 'validation' not in names: if 'validation' not in names and 'indexes' not in names:
return False return False
return True return True
@ -175,8 +175,6 @@ class CRUDData(XLSXData):
raise CRUDException(self.xlsxfile,'summary sheet missing') raise CRUDException(self.xlsxfile,'summary sheet missing')
if not 'fields' in d.keys(): if not 'fields' in d.keys():
raise CRUDException(self.xlsxfile,'fields sheet missing') raise CRUDException(self.xlsxfile,'fields sheet missing')
if not 'validation' in d.keys():
raise CRUDException(self.xlsxfile,'validation sheet missing')
if len(d['summary']) != 1: if len(d['summary']) != 1:
raise CRUDException(self.xlsxfile, 'Not summary or more than one summary') raise CRUDException(self.xlsxfile, 'Not summary or more than one summary')
self.convPrimary() self.convPrimary()
@ -251,6 +249,8 @@ class CRUDData(XLSXData):
def convIndex(self): def convIndex(self):
data = self.data data = self.data
if data.get('indexes'):
return
vs = data['validation'] vs = data['validation']
nvs = [] nvs = []
for v in vs: for v in vs: