""" 修复缺少字段关联的模板 为有 template_code 但没有字段关联的文件节点补充字段关联 """ import os import json import pymysql from typing import Dict, List # 数据库连接配置 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' } TENANT_ID = 615873064429507639 CREATED_BY = 655162080928945152 UPDATED_BY = 655162080928945152 def generate_id(): """生成ID""" import time import random timestamp = int(time.time() * 1000) random_part = random.randint(100000, 999999) return timestamp * 1000 + random_part def get_templates_without_relations(conn): """获取没有字段关联的文件节点""" cursor = conn.cursor(pymysql.cursors.DictCursor) sql = """ SELECT fc.id, fc.name, fc.template_code, fc.input_data, COUNT(ff.id) as relation_count FROM f_polic_file_config fc LEFT JOIN f_polic_file_field ff ON fc.id = ff.file_id AND ff.tenant_id = fc.tenant_id WHERE fc.tenant_id = %s AND fc.template_code IS NOT NULL AND fc.template_code != '' GROUP BY fc.id, fc.name, fc.template_code, fc.input_data HAVING relation_count = 0 ORDER BY fc.name """ cursor.execute(sql, (TENANT_ID,)) templates = cursor.fetchall() cursor.close() return templates def get_fields_by_code(conn): """获取所有字段,按字段编码索引""" cursor = conn.cursor(pymysql.cursors.DictCursor) sql = """ SELECT id, name, filed_code, field_type FROM f_polic_field WHERE tenant_id = %s """ cursor.execute(sql, (TENANT_ID,)) fields = cursor.fetchall() result = { 'by_code': {}, 'by_name': {} } for field in fields: field_code = field['filed_code'] field_name = field['name'] result['by_code'][field_code] = field result['by_name'][field_name] = field cursor.close() return result def extract_fields_from_input_data(input_data: str) -> List[str]: """从 input_data 中提取字段编码列表""" try: data = json.loads(input_data) if isinstance(input_data, str) else input_data if isinstance(data, dict): return data.get('input_fields', []) except: pass return [] def create_field_relations(conn, file_id: int, field_codes: List[str], field_type: int, db_fields: Dict, dry_run: bool = True): """创建字段关联关系""" cursor = conn.cursor() try: created_count = 0 for field_code in field_codes: field = db_fields['by_code'].get(field_code) if not field: print(f" ⚠ 字段不存在: {field_code}") continue if field['field_type'] != field_type: print(f" ⚠ 字段类型不匹配: {field_code} (期望 {field_type}, 实际 {field['field_type']})") continue if not dry_run: # 检查是否已存在 check_sql = """ SELECT id FROM f_polic_file_field WHERE tenant_id = %s AND file_id = %s AND filed_id = %s """ cursor.execute(check_sql, (TENANT_ID, file_id, field['id'])) existing = cursor.fetchone() if not existing: relation_id = generate_id() insert_sql = """ INSERT INTO f_polic_file_field (id, tenant_id, file_id, filed_id, created_time, created_by, updated_time, updated_by, state) VALUES (%s, %s, %s, %s, NOW(), %s, NOW(), %s, %s) """ cursor.execute(insert_sql, ( relation_id, TENANT_ID, file_id, field['id'], CREATED_BY, UPDATED_BY, 1 )) created_count += 1 print(f" ✓ 创建关联: {field['name']} ({field_code})") else: created_count += 1 print(f" [模拟] 将创建关联: {field_code}") if not dry_run: conn.commit() return created_count finally: cursor.close() def main(): """主函数""" print("="*80) print("修复缺少字段关联的模板") print("="*80) try: conn = pymysql.connect(**DB_CONFIG) print("✓ 数据库连接成功\n") except Exception as e: print(f"✗ 数据库连接失败: {e}") return try: # 获取没有字段关联的模板 print("查找缺少字段关联的模板...") templates = get_templates_without_relations(conn) print(f" 找到 {len(templates)} 个缺少字段关联的文件节点\n") if not templates: print("✓ 所有文件节点都有字段关联,无需修复") return # 获取所有字段 print("获取字段定义...") db_fields = get_fields_by_code(conn) print(f" 找到 {len(db_fields['by_code'])} 个字段\n") # 显示需要修复的模板 print("需要修复的模板:") for template in templates: print(f" - {template['name']} (code: {template['template_code']})") # 尝试从 input_data 中提取字段 print("\n" + "="*80) print("分析并修复") print("="*80) fixable_count = 0 unfixable_count = 0 for template in templates: print(f"\n处理: {template['name']}") print(f" template_code: {template['template_code']}") input_data = template.get('input_data') if not input_data: print(" ⚠ 没有 input_data,无法自动修复") unfixable_count += 1 continue # 从 input_data 中提取输入字段 input_fields = extract_fields_from_input_data(input_data) if not input_fields: print(" ⚠ input_data 中没有 input_fields,无法自动修复") unfixable_count += 1 continue print(f" 找到 {len(input_fields)} 个输入字段") fixable_count += 1 # 创建输入字段关联 print(" 创建输入字段关联...") created = create_field_relations(conn, template['id'], input_fields, 1, db_fields, dry_run=True) print(f" 将创建 {created} 个输入字段关联") print("\n" + "="*80) print("统计") print("="*80) print(f" 可修复: {fixable_count} 个") print(f" 无法自动修复: {unfixable_count} 个") # 询问是否执行 if fixable_count > 0: print("\n" + "="*80) response = input("\n是否执行修复?(yes/no,默认no): ").strip().lower() if response == 'yes': print("\n执行修复...") for template in templates: input_data = template.get('input_data') if not input_data: continue input_fields = extract_fields_from_input_data(input_data) if not input_fields: continue print(f"\n修复: {template['name']}") create_field_relations(conn, template['id'], input_fields, 1, db_fields, dry_run=False) print("\n" + "="*80) print("✓ 修复完成!") print("="*80) else: print("\n已取消修复") else: print("\n没有可以自动修复的模板") finally: conn.close() print("\n数据库连接已关闭") if __name__ == '__main__': main()