Files
dpb/backend/scripts/supplement_tree_status_dict.py
34047007@qq.com b95053c52c init: 初始化 dpb 桃育种系统代码库
前后端 + 后端 FastAPI 全量源码、部署脚本与文档。
2026-08-06 00:17:49 +08:00

100 lines
3.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""补充单株状态字典 tree_status:初选/重点/保存 三态,幂等。
背景:波次6 状态机要求 tree.status 覆盖完整选育流转
(存活→入选→初选→重点→保存→淘汰),而线上字典仅有
alive(存活)/selected(入选)/eliminated(淘汰) 三值。
本脚本补齐 primary(初选)/key(重点)/preserved(保存)
使导入模板下拉与状态机流转齐备。
用法(backend/ 目录):
ENVIRONMENT=dev "C:/ai/miniconda3/envs/dpb/python.exe" scripts/supplement_tree_status_dict.py --check
ENVIRONMENT=dev "C:/ai/miniconda3/envs/dpb/python.exe" scripts/supplement_tree_status_dict.py
幂等性:目标 dict_value 已存在则跳过;可重复执行。
"""
import argparse
import os
import sys
import uuid
BACKEND_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if BACKEND_DIR not in sys.path:
sys.path.insert(0, BACKEND_DIR)
from sqlalchemy import create_engine, text # noqa: E402
from app.config.setting import settings # noqa: E402
# (dict_sort, dict_label, dict_value) —— 沿用 alive=1/eliminated=2/selected=3 的序号延续
NEW_ROWS = [
(4, "初选", "primary"),
(5, "重点", "key"),
(6, "保存", "preserved"),
]
DICT_TYPE = "tree_status"
def main() -> None:
parser = argparse.ArgumentParser(description="补充 tree_status 字典三态")
parser.add_argument("--check", action="store_true", help="仅预览将插入的行,不落库")
args = parser.parse_args()
engine = create_engine(settings.DB_URI)
print(f"# 连接: {settings.DB_URI} dict_type={DICT_TYPE} 模式: {'预览' if args.check else '执行'}")
with engine.connect() as conn:
type_row = conn.execute(
text("SELECT id FROM sys_dict_type WHERE dict_type = :dt"),
{"dt": DICT_TYPE},
).first()
if not type_row:
print(f"!! 字典类型 {DICT_TYPE} 不存在,中止")
sys.exit(1)
dict_type_id = type_row[0]
existing = {
row[0]
for row in conn.execute(
text("SELECT dict_value FROM sys_dict_data WHERE dict_type = :dt"),
{"dt": DICT_TYPE},
)
}
to_insert = [(sort, label, value) for sort, label, value in NEW_ROWS if value not in existing]
missing = [value for _, _, value in NEW_ROWS if value not in existing]
print(f"# 现有值: {sorted(existing)}")
print(f"# 待补: {missing}")
if args.check:
for sort, label, value in to_insert:
print(f" + (dict_sort={sort}) {label} -> {value}")
return
if not to_insert:
print("# 无新增,幂等退出 ✅")
return
for sort, label, value in to_insert:
conn.execute(
text(
"INSERT INTO sys_dict_data "
"(status, description, dict_sort, dict_label, dict_value, css_class, list_class, "
" is_default, dict_type, dict_type_id, uuid, is_deleted, created_time, updated_time) "
"VALUES (0, '', :sort, :label, :value, '', NULL, false, :dt, :dtid, :uuid, false, now(), now())"
),
{
"sort": sort,
"label": label,
"value": value,
"dt": DICT_TYPE,
"dtid": dict_type_id,
"uuid": str(uuid.uuid4()),
},
)
conn.commit()
print("# 已插入 ✅")
if __name__ == "__main__":
main()