如何阻止VectorstoreIndexCreator加载持久化目录至内存及报错解决
问题解决:LangChain/Chroma + FastAPI 文件占用错误([WinError 32])
核心原因
Chroma 创建向量存储后,默认会保持内存连接并持有持久化目录的文件句柄,导致执行删除操作时提示文件被占用。以下是几个可行的解决方案:
方案1:显式关闭 Chroma 连接释放资源
放弃使用VectorstoreIndexCreator的隐式创建逻辑,手动实例化 Chroma 并显式关闭客户端连接,确保文件句柄被释放:
from langchain.vectorstores import Chroma from langchain.document_loaders import DirectoryLoader def createVectorStore(self): # 加载文档 loader = DirectoryLoader(path=self.__getAssetPath()) docs = loader.load() # 获取嵌入模型 embedding = self.__getVectorEmbedding() # 手动创建 Chroma 实例 chroma_db = Chroma.from_documents( documents=docs, embedding=embedding, persist_directory=self.__getPersistPath() ) # 显式持久化数据 chroma_db.persist() # 关闭客户端连接(关键步骤) chroma_db._client.close() return chroma_db
如果在 FastAPI 中通过依赖管理 Chroma 实例,需在请求结束后主动清理该实例。
方案2:调整 Chroma 加载模式,禁止自动驻留内存
使用最新版 Chroma,创建实例时指定load_into_memory=False,让 Chroma 仅在需要时从磁盘读取数据,不长期占用文件句柄:
chroma_db = Chroma.from_documents( documents=docs, embedding=embedding, persist_directory=self.__getPersistPath(), client_settings={"chroma_db_impl": "duckdb+parquet", "load_into_memory": False} )
方案3:优化删除流程,避免删除整个持久化目录
无需删除整个持久化目录,直接删除 asset 中的目标文件后,重新构建向量存储时让 Chroma 自动覆盖原有数据:
# 修改删除逻辑 filePath = os.path.join(self.__getAssetPath(), file_name) os.remove(filePath) # 直接重新创建向量存储,Chroma 会自动覆盖旧数据 _ = self.createVectorStore()
方案4:强制释放文件占用(仅测试场景)
使用psutil工具找到并终止占用文件的进程,适合测试环境,生产环境谨慎使用:
- 安装依赖:
pip install psutil - 修改
removeDirectory方法:
import psutil import os @staticmethod def removeDirectory(path): if not os.path.exists(path): return # 终止占用目标目录的进程 for proc in psutil.process_iter(['pid', 'open_files']): try: for file in proc.open_files(): if path in file.path: proc.terminate() except (psutil.NoSuchProcess, psutil.AccessDenied): pass # 执行删除操作 for root, dirs, files in os.walk(path, False): for name in files: os.remove(os.path.join(root, name)) for name in dirs: os.rmdir(os.path.join(root, name)) os.rmdir(path)
内容的提问来源于stack exchange,提问作者Miaozxje
相关产品推荐
相关产品推荐

