ai-business-write/verify_template_hierarchy.py
2025-12-26 09:32:15 +08:00

216 lines
6.9 KiB
Python
Raw 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.

"""
验证模板层级结构是否正确
"""
import os
import pymysql
from pathlib import Path
from typing import Dict, List, Optional
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
# 数据库配置
DB_CONFIG = {
'host': os.getenv('DB_HOST', '152.136.177.240'),
'port': int(os.getenv('DB_PORT', 5012)),
'user': os.getenv('DB_USER', 'finyx'),
'password': os.getenv('DB_PASSWORD', '6QsGK6MpePZDE57Z'),
'database': os.getenv('DB_NAME', 'finyx'),
'charset': 'utf8mb4'
}
def print_section(title):
"""打印章节标题"""
print("\n" + "="*70)
print(f" {title}")
print("="*70)
def get_actual_tenant_id(conn) -> int:
"""获取数据库中的实际tenant_id"""
cursor = conn.cursor(pymysql.cursors.DictCursor)
try:
cursor.execute("SELECT DISTINCT tenant_id FROM f_polic_file_config LIMIT 1")
result = cursor.fetchone()
if result:
return result['tenant_id']
return 1
finally:
cursor.close()
def print_hierarchy(conn, tenant_id: int, parent_id: Optional[int] = None, level: int = 0, prefix: str = ""):
"""递归打印层级结构"""
cursor = conn.cursor(pymysql.cursors.DictCursor)
try:
if parent_id is None:
sql = """
SELECT id, name, file_path, parent_id
FROM f_polic_file_config
WHERE tenant_id = %s AND parent_id IS NULL
ORDER BY name
"""
cursor.execute(sql, (tenant_id,))
else:
sql = """
SELECT id, name, file_path, parent_id
FROM f_polic_file_config
WHERE tenant_id = %s AND parent_id = %s
ORDER BY name
"""
cursor.execute(sql, (tenant_id, parent_id))
items = cursor.fetchall()
for i, item in enumerate(items):
is_last = (i == len(items) - 1)
current_prefix = "└── " if is_last else "├── "
next_prefix = prefix + (" " if is_last else "")
if item['file_path']:
# 文件节点
print(f"{prefix}{current_prefix}{item['name']} (文件, ID: {item['id']})")
else:
# 目录节点
print(f"{prefix}{current_prefix}{item['name']} (目录, ID: {item['id']})")
# 递归打印子节点
print_hierarchy(conn, tenant_id, item['id'], level + 1, next_prefix)
finally:
cursor.close()
def verify_hierarchy(conn, tenant_id: int):
"""验证层级结构"""
print_section("验证模板层级结构")
cursor = conn.cursor(pymysql.cursors.DictCursor)
try:
# 1. 统计信息
print("1. 统计信息:")
# 根节点parent_id为NULL
cursor.execute("""
SELECT COUNT(*) as count
FROM f_polic_file_config
WHERE tenant_id = %s AND parent_id IS NULL
""", (tenant_id,))
root_count = cursor.fetchone()['count']
print(f" 根节点: {root_count}")
# 目录节点file_path为NULL
cursor.execute("""
SELECT COUNT(*) as count
FROM f_polic_file_config
WHERE tenant_id = %s AND file_path IS NULL
""", (tenant_id,))
dir_count = cursor.fetchone()['count']
print(f" 目录节点: {dir_count}")
# 文件节点file_path不为NULL
cursor.execute("""
SELECT COUNT(*) as count
FROM f_polic_file_config
WHERE tenant_id = %s AND file_path IS NOT NULL
""", (tenant_id,))
file_count = cursor.fetchone()['count']
print(f" 文件节点: {file_count}")
# 有父级的文件
cursor.execute("""
SELECT COUNT(*) as count
FROM f_polic_file_config
WHERE tenant_id = %s
AND file_path IS NOT NULL
AND parent_id IS NOT NULL
""", (tenant_id,))
file_with_parent = cursor.fetchone()['count']
print(f" 有父级的文件: {file_with_parent}")
# 没有父级的文件
cursor.execute("""
SELECT COUNT(*) as count
FROM f_polic_file_config
WHERE tenant_id = %s
AND file_path IS NOT NULL
AND parent_id IS NULL
""", (tenant_id,))
file_without_parent = cursor.fetchone()['count']
print(f" 没有父级的文件: {file_without_parent}")
# 2. 显示层级结构
print("\n2. 层级结构:")
print_hierarchy(conn, tenant_id)
# 3. 检查问题
print("\n3. 检查潜在问题:")
# 检查是否有孤立的文件(没有父级,但应该在某个目录下)
cursor.execute("""
SELECT id, name, file_path
FROM f_polic_file_config
WHERE tenant_id = %s
AND file_path IS NOT NULL
AND parent_id IS NULL
AND file_path LIKE 'template_finish/%%/%%'
""", (tenant_id,))
isolated_files = cursor.fetchall()
if isolated_files:
print(f" [警告] 发现 {len(isolated_files)} 个可能孤立的文件(有路径但无父级):")
for file in isolated_files[:5]:
print(f" - {file['name']} (ID: {file['id']})")
print(f" 路径: {file['file_path']}")
else:
print(" [OK] 没有发现孤立的文件")
# 检查是否有循环引用
cursor.execute("""
SELECT t1.id, t1.name, t1.parent_id, t2.id as parent_exists
FROM f_polic_file_config t1
LEFT JOIN f_polic_file_config t2 ON t1.parent_id = t2.id AND t1.tenant_id = t2.tenant_id
WHERE t1.tenant_id = %s
AND t1.parent_id IS NOT NULL
AND t2.id IS NULL
""", (tenant_id,))
broken_links = cursor.fetchall()
if broken_links:
print(f" [警告] 发现 {len(broken_links)} 个断开的父级链接:")
for link in broken_links[:5]:
print(f" - {link['name']} (ID: {link['id']}, parent_id: {link['parent_id']})")
else:
print(" [OK] 没有发现断开的父级链接")
finally:
cursor.close()
def main():
"""主函数"""
print_section("验证模板层级结构")
try:
conn = pymysql.connect(**DB_CONFIG)
print("[OK] 数据库连接成功")
except Exception as e:
print(f"[FAIL] 数据库连接失败: {str(e)}")
return
try:
tenant_id = get_actual_tenant_id(conn)
print(f"实际tenant_id: {tenant_id}")
verify_hierarchy(conn, tenant_id)
finally:
conn.close()
print("\n[OK] 数据库连接已关闭")
if __name__ == "__main__":
main()