ai-business-write/fix_missing_field_relations.py

261 lines
8.3 KiB
Python
Raw Permalink 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.

"""
修复缺少字段关联的模板
为有 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()