You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止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工具找到并终止占用文件的进程,适合测试环境,生产环境谨慎使用:

  1. 安装依赖:pip install psutil
  2. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 15:02:49