100 lines
3.5 KiB
Python
100 lines
3.5 KiB
Python
"""补充单株状态字典 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()
|