feat(scripts): 添加 Milvus 集合重命名脚本

添加用于重命名 Milvus 集合的脚本,自动处理重复集合情况
更新文档中的测试说明和代码规范要求
This commit is contained in:
Wenjie Zhang 2025-08-25 02:27:02 +08:00
parent afaba5c8cb
commit eb04d1f2c4
3 changed files with 82 additions and 0 deletions

View File

@ -27,6 +27,7 @@
- [ ] 使用其他的聊天记录管理方法(现在是基于 LangGraph 的 Memory 实现的) - [ ] 使用其他的聊天记录管理方法(现在是基于 LangGraph 的 Memory 实现的)
- [ ] 添加测试脚本,覆盖最常见的功能
- [ ] 封装现有工具为 mcpstdio调用 - [ ] 封装现有工具为 mcpstdio调用
- [ ] 支持额外 mcp 配置(代码端) - [ ] 支持额外 mcp 配置(代码端)
- [ ] 添加用户日志与用户反馈模块,可以在 AgentView 中查看信息 - [ ] 添加用户日志与用户反馈模块,可以在 AgentView 中查看信息

View File

@ -34,7 +34,10 @@ Yuxi-Know/
此项目是使用 Docker 进行部署的,使用 `docker compose up -d` 命令进行构建和启动。因此当进行任何修改的时候,不要尝试启动这个项目,应该先检查项目是否已经在后台启动(`docker ps`),具体的可以阅读 [docker-compose.yml](docker-compose.yml). 此项目是使用 Docker 进行部署的,使用 `docker compose up -d` 命令进行构建和启动。因此当进行任何修改的时候,不要尝试启动这个项目,应该先检查项目是否已经在后台启动(`docker ps`),具体的可以阅读 [docker-compose.yml](docker-compose.yml).
前端和后端都是配置了自动启动的,因此当修改完成后,会自动更新,可以使用 docker logs 查看日志。对于部分场景可以创建一个 test_router.py 在 [server/routers](server/routers) 中,然后通过 API 测试功能场景。对于前端的 UI 修改,则不用测试。 前端和后端都是配置了自动启动的,因此当修改完成后,会自动更新,可以使用 docker logs 查看日志。对于部分场景可以创建一个 test_router.py 在 [server/routers](server/routers) 中,然后通过 API 测试功能场景。对于前端的 UI 修改,则不用测试。
对于后端的修改,可以写个独立的脚本尝试调用 API比如 [test_api.py](scripts/test_api.py)。注意使用 `uv run` 来执行脚本。
## 风格说明 ## 风格说明
UI风格要简洁同时要保持一致性颜色要尽量参考 [base.css](web/src/assets/css/base.css) 中的颜色。不要悬停位移,不要过度使用阴影以及渐变色。 UI风格要简洁同时要保持一致性颜色要尽量参考 [base.css](web/src/assets/css/base.css) 中的颜色。不要悬停位移,不要过度使用阴影以及渐变色。
Python 代码要符合 Python 的规范,尽量使用较新的语法,避免使用旧版本的语法(版本兼容到 3.12+),使用 uvx ruff check 检查 lint。

View File

@ -0,0 +1,78 @@
import os
from pymilvus import utility, connections, Collection
def get_collection_info(collection_name, alias):
"""Safely gets a collection object and its number of entities."""
try:
collection = Collection(collection_name, using=alias)
collection.load()
return collection, collection.num_entities
except Exception as e:
print(f"Error getting info for collection '{collection_name}': {e}")
return None, 0
def rename_and_resolve_duplicates():
"""
Connects to Milvus, renames collections from 'kb_kb_' to 'kb_',
and resolves duplicates by keeping the collection with more rows.
"""
milvus_uri = os.getenv('MILVUS_URI', 'http://localhost:19530')
milvus_token = os.getenv('MILVUS_TOKEN', '')
connection_alias = "rename_script"
try:
print(f"Connecting to Milvus at {milvus_uri}...")
connections.connect(alias=connection_alias, uri=milvus_uri, token=milvus_token)
print("Successfully connected to Milvus.")
all_collections = utility.list_collections(using=connection_alias)
collections_to_rename = [c for c in all_collections if c.startswith('kb_kb_')]
if not collections_to_rename:
print("No collections with the prefix 'kb_kb_' found. Nothing to do.")
return
print(f"Found {len(collections_to_rename)} collections with 'kb_kb_' prefix to process.")
for old_name in collections_to_rename:
new_name = old_name.replace('kb_kb_', 'kb_', 1)
try:
print(f"Attempting to rename '{old_name}' to '{new_name}'...")
utility.rename_collection(old_name, new_name, using=connection_alias)
print(f"Successfully renamed '{old_name}' to '{new_name}'.")
except Exception as e:
# Check if it's a duplicate name error
if "duplicated new collection name" in str(e):
print(f"Rename failed: Target collection '{new_name}' already exists. Resolving duplicate...")
# Get info for both collections
old_coll, old_count = get_collection_info(old_name, connection_alias)
new_coll, new_count = get_collection_info(new_name, connection_alias)
print(f"Comparing row counts: '{old_name}' ({old_count} rows) vs '{new_name}' ({new_count} rows).")
if old_count > new_count:
print(f"'{old_name}' has more rows. Deleting '{new_name}' and retrying rename.")
utility.drop_collection(new_name, using=connection_alias)
print(f"Dropped collection '{new_name}'.")
# Retry renaming
utility.rename_collection(old_name, new_name, using=connection_alias)
print(f"Successfully renamed '{old_name}' to '{new_name}'.")
else:
print(f"'{new_name}' has more or equal rows. Deleting '{old_name}'.")
utility.drop_collection(old_name, using=connection_alias)
print(f"Dropped collection '{old_name}'.")
else:
print(f"An unexpected error occurred while renaming '{old_name}': {e}")
print("\nProcess finished.")
except Exception as e:
print(f"A critical error occurred: {e}")
finally:
if connection_alias in connections.list_connections():
connections.disconnect(connection_alias)
print("Disconnected from Milvus.")
if __name__ == "__main__":
rename_and_resolve_duplicates()