第一次
This commit is contained in:
86
scripts/fst_sql_tool/print_tree.py
Normal file
86
scripts/fst_sql_tool/print_tree.py
Normal file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import psycopg2
|
||||
import os
|
||||
import sys
|
||||
from dotenv import load_dotenv
|
||||
|
||||
|
||||
load_dotenv("../../.env", override=True)
|
||||
DB_CONFIG = {
|
||||
"host": os.getenv("ROOT_DB_HOST", "localhost"),
|
||||
"port": os.getenv("ROOT_DB_PORT", "5432"),
|
||||
"dbname": os.getenv("ROOT_DB_NAME", "mydb"),
|
||||
"user": os.getenv("ROOT_DB_USER", "postgres"),
|
||||
"password": os.getenv("ROOT_DB_PASSWD", "postgres"),
|
||||
}
|
||||
|
||||
|
||||
def fetch_nodes():
|
||||
conn = psycopg2.connect(**DB_CONFIG)
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT id, name, parent_id FROM fst")
|
||||
rows = cur.fetchall()
|
||||
cur.close()
|
||||
conn.close()
|
||||
return rows
|
||||
|
||||
|
||||
def build_tree(rows):
|
||||
nodes = {}
|
||||
for id_, name, parent_id in rows:
|
||||
nodes[id_] = {"id": id_, "name": name, "parent_id": parent_id, "children": []}
|
||||
roots = []
|
||||
for n in nodes.values():
|
||||
if n["parent_id"] is None or n["parent_id"] not in nodes:
|
||||
roots.append(n)
|
||||
else:
|
||||
nodes[n["parent_id"]]["children"].append(n)
|
||||
|
||||
def sort_rec(n):
|
||||
n["children"].sort(key=lambda x: x["name"])
|
||||
for c in n["children"]:
|
||||
sort_rec(c)
|
||||
|
||||
for r in roots:
|
||||
sort_rec(r)
|
||||
return roots
|
||||
|
||||
|
||||
def print_subtree(node, prefix="", is_last=True, depth=0):
|
||||
# depth==0: 根节点;depth>=1: 各层子节点
|
||||
if depth == 0:
|
||||
# 根直接打印名字
|
||||
print(node["name"])
|
||||
else:
|
||||
# 非根:打印前置 prefix + 连接符 + 名字
|
||||
connector = "└── " if is_last else "├── "
|
||||
print(prefix + connector + node["name"])
|
||||
# 计算传给下一层孩子的前缀
|
||||
if depth == 0:
|
||||
# 第一层孩子不缩进,prefix 仍然空
|
||||
child_prefix = ""
|
||||
else:
|
||||
# depth>=1:如果我是本层最后一个,用空格填充,否则保留竖线
|
||||
child_prefix = prefix + (" " if is_last else "│ ")
|
||||
# 递归打印子节点
|
||||
cnt = len(node["children"])
|
||||
for idx, child in enumerate(node["children"]):
|
||||
last = idx == cnt - 1
|
||||
print_subtree(child, child_prefix, last, depth + 1)
|
||||
|
||||
|
||||
def main():
|
||||
rows = fetch_nodes()
|
||||
if not rows:
|
||||
print("fst 表中没有数据。", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
roots = build_tree(rows)
|
||||
for idx, r in enumerate(roots):
|
||||
last_root = idx == len(roots) - 1
|
||||
print_subtree(r, prefix="", is_last=last_root, depth=0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user