重新创建ChromaDB嵌入时提示‘Could not connect to tenant’的问题咨询
问题:删除ChromaDB嵌入后重建失败,重启应用才恢复的解决方案
我开发了一款提供自定义GPT机器人服务的RAG应用,按bot_id分别存储GPT回答用户查询所用文件的嵌入。当用户修改文件URL时,我用shutil.rmtree("Embeddings/1001")成功删除了对应bot的ChromaDB文件夹,但重新创建嵌入时出现以下错误:
Traceback (most recent call last): File "/home/ubuntu/.local/lib/python3.10/site-packages/chromadb/api/client.py", line 438, in _validate_tenant_database self._admin_client.get_tenant(name=tenant) File "/home/ubuntu/.local/lib/python3.10/site-packages/chromadb/api/client.py", line 486, in get_tenant return self._server.get_tenant(name=name) File "/home/ubuntu/.local/lib/python3.10/site-packages/chromadb/api/segment.py", line 140, in get_tenant return self._sysdb.get_tenant(name=name) File "/home/ubuntu/.local/lib/python3.10/site-packages/chromadb/db/mixins/sysdb.py", line 125, in get_tenant with self.tx() as cur: File "/home/ubuntu/.local/lib/python3.10/site-packages/chromadb/db/impl/sqlite.py", line 131, in tx return TxWrapper(self._conn_pool, stack=self._tx_stack) File "/home/ubuntu/.local/lib/python3.10/site-packages/chromadb/db/impl/sqlite.py", line 31, in __init__ self._conn = conn_pool.connect() File "/home/ubuntu/.local/lib/python3.10/site-packages/chromadb/db/impl/sqlite_pool.py", line 141, in connect new_connection = Connection( File "/home/ubuntu/.local/lib/python3.10/site-packages/chromadb/db/impl/sqlite_pool.py", line 20, in __init__ self._conn = sqlite3.connect( sqlite3.OperationalError: unable to open database file During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/ubuntu/.local/lib/python3.10/site-packages/flask/app.py", line 1463, in wsgi_app response = self.full_dispatch_request() File "/home/ubuntu/.local/lib/python3.10/site-packages/flask/app.py", line 872, in full_dispatch_request rv = self.handle_user_exception(e) File "/home/ubuntu/.local/lib/python3.10/site-packages/flask/app.py", line 870, in full_dispatch_request rv = self.dispatch_request() File "/home/ubuntu/.local/lib/python3.10/site-packages/flask/app.py", line 855, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return] File "/home/ubuntu/chatbot/main.py", line 460, in qa message = storeEmbeddings(embedding_model, raw_text, bot_id) File "/home/ubuntu/chatbot/embeddings.py", line 12, in storeEmbeddings db = Chroma.from_documents( File "/home/ubuntu/.local/lib/python3.10/site-packages/langchain_community/vectorstores/chroma.py", line 778, in from_documents return cls.from_texts( File "/home/ubuntu/.local/lib/python3.10/site-packages/langchain_community/vectorstores/chroma.py", line 714, in from_texts chroma_collection = cls( File "/home/ubuntu/.local/lib/python3.10/site-packages/langchain_community/vectorstores/chroma.py", line 120, in __init__ self._client = chromadb.Client(_client_settings) File "/home/ubuntu/.local/lib/python3.10/site-packages/chromadb/__init__.py", line 274, in Client return ClientCreator(tenant=tenant, database=database, settings=settings) File "/home/ubuntu/.local/lib/python3.10/site-packages/chromadb/api/client.py", line 144, in __init__ self._validate_tenant_database(tenant=tenant, database=database) File "/home/ubuntu/.local/lib/python3.10/site-packages/chromadb/api/client.py", line 447, in _validate_tenant_database raise ValueError( ValueError: Could not connect to tenant default_tenant. Are you sure it exists?
虽然文件夹已经成功删除,但系统似乎仍在尝试访问旧的ChromaDB连接。我的嵌入创建存储函数如下:
def storeEmbeddings(embedding, text, bot_id, embedding_folder): try: text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200) texts = text_splitter.create_documents([text]) db = Chroma.from_documents( texts, embedding, persist_directory=embedding_folder+"//"+bot_id, client_settings=Settings(anonymized_telemetry=False,is_persistent=True,), ) return sucessMessage except Exception as e: return str(e)
重启Python应用后可以正常重建嵌入,请问删除现有ChromaDB嵌入并为新文档创建嵌入的最佳方式是什么?
解决方案
核心原因
直接删除文件夹后,ChromaDB的客户端连接池仍持有对旧数据库文件的引用,导致无法创建新连接,必须重启应用释放这些引用。
最佳实践
1. 使用ChromaDB官方API删除集合,而非直接删文件夹
不要手动删除目录,而是通过ChromaDB的API先删除对应bot_id的集合,再重新创建:
def storeEmbeddings(embedding, text, bot_id, embedding_folder): try: # 初始化Chroma客户端 client_settings = Settings(anonymized_telemetry=False, is_persistent=True) client = chromadb.Client(client_settings) # 先删除已存在的集合(如果有) try: client.delete_collection(name=f"bot_{bot_id}") except ValueError: # 集合不存在时忽略错误 pass # 分割文本并创建新集合 text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200) texts = text_splitter.create_documents([text]) db = Chroma.from_documents( texts, embedding, collection_name=f"bot_{bot_id}", persist_directory=embedding_folder+"//"+bot_id, client_settings=client_settings, ) return "成功创建嵌入" except Exception as e: return str(e)
2. 手动删文件夹后,强制关闭并重新初始化Chroma客户端
如果必须手动删除目录,需要在删除后关闭现有客户端连接,再重新创建:
import shutil import os from chromadb.api.client import Client # 全局存储客户端实例(如果有的话) chroma_clients = {} def delete_and_recreate_embeddings(embedding, text, bot_id, embedding_folder): try: # 删除旧文件夹 emb_path = f"{embedding_folder}//{bot_id}" if os.path.exists(emb_path): shutil.rmtree(emb_path) # 关闭对应客户端(如果存在) if bot_id in chroma_clients: chroma_clients[bot_id].reset() del chroma_clients[bot_id] # 重新创建嵌入 text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200) texts = text_splitter.create_documents([text]) client_settings = Settings(anonymized_telemetry=False, is_persistent=True) db = Chroma.from_documents( texts, embedding, persist_directory=emb_path, client_settings=client_settings, ) # 保存客户端实例以便后续管理 chroma_clients[bot_id] = db._client return "成功创建嵌入" except Exception as e: return str(e)
3. 避免全局客户端实例复用问题
如果你的应用中使用了全局的Chroma客户端,删除文件夹后客户端仍会尝试访问旧的连接池。建议为每个bot_id创建独立的客户端实例,或者在删除操作后显式重置客户端。
内容的提问来源于stack exchange,提问作者Asif Mehmood
相关产品推荐
相关产品推荐

