PyInstaller打包含SQLite驱动的Exe触发NotADirectoryError求助
解决PyInstaller打包chromadb应用时的NotADirectoryError问题
问题根源
PyInstaller打包后,chromadb依赖的迁移文件目录结构被破坏,导致files("chromadb.migrations.embeddings_queue")无法识别正确的目录路径,触发MultiplexedPath only supports directories错误。
解决方案步骤
1. 修改app.spec,确保迁移文件被正确打包
在app.spec的datas列表中添加chromadb迁移目录的打包规则,把conda环境里的chromadb migrations目录映射到打包后的对应路径:
# app.spec示例内容 a = Analysis( ['your_app.py'], pathex=[], binaries=[], # 重点添加下面这行datas配置 datas=[(r'你的conda环境路径/lib/python3.10/site-packages/chromadb/migrations', 'chromadb/migrations')], ... )
注意:替换你的conda环境路径为实际路径,比如C:\Users\XXX\miniconda3\envs\你的环境名
2. 在代码中检测frozen环境并指定迁移路径
在初始化chromadb客户端前,判断是否处于打包后的frozen环境,手动指定迁移文件目录:
import sys import os import chromadb from chromadb.config import Settings def get_chromadb_settings(): if getattr(sys, 'frozen', False): # 打包后PyInstaller会把资源解压到sys._MEIPASS临时目录 migrations_dir = os.path.join(sys._MEIPASS, 'chromadb', 'migrations') return Settings(migrations_directory=migrations_dir) return Settings() # 用自定义配置初始化客户端 client = chromadb.Client(get_chromadb_settings())
3. (可选)Monkey Patch修复files函数调用
如果上述步骤仍报错,直接修正chromadb内部的files调用逻辑,在代码最开头添加:
import sys from importlib.resources import files as original_files def patched_files(package): if getattr(sys, 'frozen', False) and package == "chromadb.migrations.embeddings_queue": # 绕过原调用,直接返回embeddings_queue所在的目录对象 return original_files("chromadb.migrations").joinpath("embeddings_queue") return original_files(package) # 替换chromadb.sqlite中的files函数 import chromadb.sqlite chromadb.sqlite.files = patched_files
4. 重新打包
执行原打包命令:
python -m PyInstaller --noconfirm app.spec
内容的提问来源于stack exchange,提问作者CarbonMan
相关产品推荐
相关产品推荐

