""" 验证模板字段同步结果 检查 input_data、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 def verify_template_configs(conn): """验证模板配置的 input_data 和 template_code""" cursor = conn.cursor(pymysql.cursors.DictCursor) print("="*80) print("验证模板配置") print("="*80) sql = """ SELECT id, name, template_code, input_data, parent_id FROM f_polic_file_config WHERE tenant_id = %s ORDER BY parent_id, name """ cursor.execute(sql, (TENANT_ID,)) configs = cursor.fetchall() print(f"\n共 {len(configs)} 个模板配置\n") # 统计 has_template_code = 0 has_input_data = 0 has_both = 0 missing_both = 0 # 文件节点(有 template_code 的) file_nodes = [] # 目录节点(没有 template_code 的) dir_nodes = [] for config in configs: template_code = config.get('template_code') input_data = config.get('input_data') if template_code: has_template_code += 1 file_nodes.append(config) else: dir_nodes.append(config) if input_data: has_input_data += 1 try: input_data_dict = json.loads(input_data) if isinstance(input_data, str) else input_data if isinstance(input_data_dict, dict) and input_data_dict.get('template_code'): has_both += 1 except: pass if not template_code and not input_data: missing_both += 1 print("统计信息:") print(f" 文件节点(有 template_code): {len(file_nodes)} 个") print(f" 目录节点(无 template_code): {len(dir_nodes)} 个") print(f" 有 input_data: {has_input_data} 个") print(f" 同时有 template_code 和 input_data: {has_both} 个") print(f" 两者都没有: {missing_both} 个") # 检查文件节点的 input_data print("\n文件节点 input_data 检查:") missing_input_data = [] for config in file_nodes: input_data = config.get('input_data') if not input_data: missing_input_data.append(config) else: try: input_data_dict = json.loads(input_data) if isinstance(input_data, str) else input_data if not isinstance(input_data_dict, dict) or 'template_code' not in input_data_dict: missing_input_data.append(config) except: missing_input_data.append(config) if missing_input_data: print(f" ⚠ 有 {len(missing_input_data)} 个文件节点缺少或格式错误的 input_data:") for config in missing_input_data[:10]: # 只显示前10个 print(f" - {config['name']} (ID: {config['id']})") if len(missing_input_data) > 10: print(f" ... 还有 {len(missing_input_data) - 10} 个") else: print(" ✓ 所有文件节点都有正确的 input_data") cursor.close() return { 'total': len(configs), 'file_nodes': len(file_nodes), 'dir_nodes': len(dir_nodes), 'has_input_data': has_input_data, 'has_both': has_both, 'missing_input_data': len(missing_input_data) } def verify_field_relations(conn): """验证字段关联关系""" cursor = conn.cursor(pymysql.cursors.DictCursor) print("\n" + "="*80) print("验证字段关联关系") print("="*80) # 获取所有文件节点的字段关联 sql = """ SELECT fc.id as file_id, fc.name as file_name, fc.template_code, COUNT(ff.id) as field_count, SUM(CASE WHEN f.field_type = 1 THEN 1 ELSE 0 END) as input_field_count, SUM(CASE WHEN f.field_type = 2 THEN 1 ELSE 0 END) as output_field_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 LEFT JOIN f_polic_field f ON ff.filed_id = f.id AND f.tenant_id = fc.tenant_id WHERE fc.tenant_id = %s AND fc.template_code IS NOT NULL GROUP BY fc.id, fc.name, fc.template_code ORDER BY fc.name """ cursor.execute(sql, (TENANT_ID,)) relations = cursor.fetchall() print(f"\n共 {len(relations)} 个文件节点有字段关联\n") # 统计 has_relations = 0 no_relations = 0 has_input_fields = 0 has_output_fields = 0 no_relation_templates = [] for rel in relations: field_count = rel['field_count'] or 0 input_count = rel['input_field_count'] or 0 output_count = rel['output_field_count'] or 0 if field_count > 0: has_relations += 1 if input_count > 0: has_input_fields += 1 if output_count > 0: has_output_fields += 1 else: no_relations += 1 no_relation_templates.append(rel) print("统计信息:") print(f" 有字段关联: {has_relations} 个") print(f" 无字段关联: {no_relations} 个") print(f" 有输入字段: {has_input_fields} 个") print(f" 有输出字段: {has_output_fields} 个") if no_relation_templates: print(f"\n ⚠ 有 {len(no_relation_templates)} 个文件节点没有字段关联:") for rel in no_relation_templates[:10]: print(f" - {rel['file_name']} (code: {rel['template_code']})") if len(no_relation_templates) > 10: print(f" ... 还有 {len(no_relation_templates) - 10} 个") else: print("\n ✓ 所有文件节点都有字段关联") # 显示详细的关联信息(前10个) print("\n字段关联详情(前10个):") for rel in relations[:10]: print(f"\n {rel['file_name']} (code: {rel['template_code']})") print(f" 总字段数: {rel['field_count']}") print(f" 输入字段: {rel['input_field_count']}") print(f" 输出字段: {rel['output_field_count']}") cursor.close() return { 'total': len(relations), 'has_relations': has_relations, 'no_relations': no_relations, 'has_input_fields': has_input_fields, 'has_output_fields': has_output_fields } def verify_input_data_structure(conn): """验证 input_data 的结构""" cursor = conn.cursor(pymysql.cursors.DictCursor) print("\n" + "="*80) print("验证 input_data 结构") print("="*80) sql = """ SELECT id, name, template_code, input_data FROM f_polic_file_config WHERE tenant_id = %s AND template_code IS NOT NULL AND input_data IS NOT NULL """ cursor.execute(sql, (TENANT_ID,)) configs = cursor.fetchall() print(f"\n检查 {len(configs)} 个有 input_data 的文件节点\n") correct_structure = 0 incorrect_structure = 0 incorrect_items = [] for config in configs: try: input_data = json.loads(config['input_data']) if isinstance(config['input_data'], str) else config['input_data'] if not isinstance(input_data, dict): incorrect_structure += 1 incorrect_items.append({ 'name': config['name'], 'reason': 'input_data 不是字典格式' }) continue # 检查必需字段 required_fields = ['template_code', 'business_type'] missing_fields = [f for f in required_fields if f not in input_data] if missing_fields: incorrect_structure += 1 incorrect_items.append({ 'name': config['name'], 'reason': f'缺少字段: {", ".join(missing_fields)}' }) continue # 检查 template_code 是否匹配 if input_data.get('template_code') != config.get('template_code'): incorrect_structure += 1 incorrect_items.append({ 'name': config['name'], 'reason': f"template_code 不匹配: input_data中为 '{input_data.get('template_code')}', 字段中为 '{config.get('template_code')}'" }) continue correct_structure += 1 except json.JSONDecodeError as e: incorrect_structure += 1 incorrect_items.append({ 'name': config['name'], 'reason': f'JSON解析错误: {str(e)}' }) except Exception as e: incorrect_structure += 1 incorrect_items.append({ 'name': config['name'], 'reason': f'其他错误: {str(e)}' }) print(f" 结构正确: {correct_structure} 个") print(f" 结构错误: {incorrect_structure} 个") if incorrect_items: print("\n 错误详情:") for item in incorrect_items[:10]: print(f" - {item['name']}: {item['reason']}") if len(incorrect_items) > 10: print(f" ... 还有 {len(incorrect_items) - 10} 个错误") else: print("\n ✓ 所有 input_data 结构都正确") cursor.close() return { 'correct': correct_structure, 'incorrect': incorrect_structure } def main(): """主函数""" print("="*80) print("验证模板字段同步结果") print("="*80) try: conn = pymysql.connect(**DB_CONFIG) print("✓ 数据库连接成功\n") except Exception as e: print(f"✗ 数据库连接失败: {e}") return try: # 验证模板配置 config_stats = verify_template_configs(conn) # 验证字段关联 relation_stats = verify_field_relations(conn) # 验证 input_data 结构 input_data_stats = verify_input_data_structure(conn) # 总结 print("\n" + "="*80) print("验证总结") print("="*80) print(f"模板配置:") print(f" - 总模板数: {config_stats['total']}") print(f" - 文件节点: {config_stats['file_nodes']}") print(f" - 缺少 input_data: {config_stats['missing_input_data']} 个") print(f"\n字段关联:") print(f" - 有字段关联: {relation_stats['has_relations']} 个") print(f" - 无字段关联: {relation_stats['no_relations']} 个") print(f"\ninput_data 结构:") print(f" - 正确: {input_data_stats['correct']} 个") print(f" - 错误: {input_data_stats['incorrect']} 个") # 总体评估 print("\n" + "="*80) if (config_stats['missing_input_data'] == 0 and relation_stats['no_relations'] == 0 and input_data_stats['incorrect'] == 0): print("✓ 所有验证通过!同步成功!") else: print("⚠ 发现一些问题,请检查上述详情") finally: conn.close() print("\n数据库连接已关闭") if __name__ == '__main__': main()