migrate_tools.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #!/usr/bin/env python3
  2. """
  3. 迁移 SQLite resources 表中的 tool 数据到 PostgreSQL tool_table
  4. """
  5. import os
  6. import json
  7. import sqlite3
  8. import psycopg2
  9. from psycopg2.extras import RealDictCursor
  10. from dotenv import load_dotenv
  11. from datetime import datetime
  12. load_dotenv()
  13. def migrate_tools():
  14. # 连接 SQLite
  15. sqlite_conn = sqlite3.connect('/root/Agent/knowhub/knowhub.db')
  16. sqlite_conn.row_factory = sqlite3.Row
  17. sqlite_cur = sqlite_conn.cursor()
  18. # 连接 PostgreSQL
  19. pg_conn = psycopg2.connect(
  20. host=os.getenv('KNOWHUB_DB'),
  21. port=int(os.getenv('KNOWHUB_PORT', 5432)),
  22. user=os.getenv('KNOWHUB_USER'),
  23. password=os.getenv('KNOWHUB_PASSWORD'),
  24. database=os.getenv('KNOWHUB_DB_NAME')
  25. )
  26. pg_conn.autocommit = False
  27. pg_cur = pg_conn.cursor(cursor_factory=RealDictCursor)
  28. # 读取所有 tool 类型数据
  29. sqlite_cur.execute("SELECT * FROM resources WHERE content_type='tool';")
  30. tools = sqlite_cur.fetchall()
  31. print(f"找到 {len(tools)} 条 tool 数据")
  32. success = 0
  33. failed = 0
  34. for tool in tools:
  35. try:
  36. metadata = json.loads(tool['metadata']) if tool['metadata'] else {}
  37. # 转换时间戳
  38. updated_time = None
  39. if tool['updated_at']:
  40. dt = datetime.fromisoformat(tool['updated_at'].replace('+00:00', ''))
  41. updated_time = int(dt.timestamp())
  42. # 插入数据
  43. pg_cur.execute("""
  44. INSERT INTO tool_table (
  45. id, name, version, introduction, tutorial, input, output,
  46. updated_time, status, knowledge, case_knowledge, process_knowledge
  47. ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
  48. ON CONFLICT (id) DO UPDATE SET
  49. name = EXCLUDED.name,
  50. version = EXCLUDED.version,
  51. introduction = EXCLUDED.introduction,
  52. tutorial = EXCLUDED.tutorial,
  53. input = EXCLUDED.input,
  54. output = EXCLUDED.output,
  55. updated_time = EXCLUDED.updated_time,
  56. status = EXCLUDED.status,
  57. knowledge = EXCLUDED.knowledge
  58. """, (
  59. tool['id'],
  60. metadata.get('tool_name'),
  61. metadata.get('version'),
  62. metadata.get('description'),
  63. metadata.get('usage'),
  64. json.dumps(metadata.get('input')) if metadata.get('input') else None,
  65. json.dumps(metadata.get('output')) if metadata.get('output') else None,
  66. updated_time,
  67. metadata.get('status', '未接入'),
  68. json.dumps(metadata.get('knowledge_ids', [])),
  69. json.dumps([]),
  70. json.dumps([])
  71. ))
  72. success += 1
  73. except Exception as e:
  74. print(f"❌ 迁移失败 {tool['id']}: {e}")
  75. failed += 1
  76. pg_conn.commit()
  77. print(f"\n✅ 迁移完成: 成功 {success} 条, 失败 {failed} 条")
  78. sqlite_conn.close()
  79. pg_conn.close()
  80. if __name__ == "__main__":
  81. migrate_tools()