含RavenDB的Python脚本转EXE后运行报错OSError: could not get source code
解决RavenDB打包EXE时的OSError: could not get source code问题
问题场景
将包含RavenDB数据库操作的Python脚本通过PyInstaller、cx_Freeze或Auto PY to EXE工具打包为EXE文件后,打包过程显示成功,但运行生成的EXE时触发以下错误:
OSError: could not get source code
[2212] Failed to execute script 'main' due to unhandled exception
涉及的Python脚本代码如下:
from ravendb import DocumentStore URLS = "http://127.0.0.1:8080/" DB_NAME = "sa" store = DocumentStore(urls=URLS, database=DB_NAME) store.initialize() class Foo(object): def __init__(self, name, key = None): self.name = name self.key = key class FooBar(object): def __init__(self, name, foo): self.name = name self.foo = foo with store.open_session() as session: foo = Foo("PyRyDB") session.store(foo) session.save_changes()
原因分析
RavenDB的Python客户端在序列化自定义类时,会尝试动态读取类的源代码生成序列化元数据,但打包工具会将Python代码编译为字节码并压缩,导致客户端无法获取到源码,从而触发该错误。
解决方法
方法一:代码层面禁用源码依赖
直接修改脚本,通过配置RavenDB的序列化约定或给自定义类添加标识,避免客户端读取源码:
from ravendb import DocumentStore URLS = "http://127.0.0.1:8080/" DB_NAME = "sa" store = DocumentStore(urls=URLS, database=DB_NAME) # 方案1:修改序列化约定,跳过源码获取 store.conventions.find_collection_name_for_type = lambda t: t.__name__ # 可选:添加更多序列化配置,确保兼容性 store.conventions.should_save_enums_as_integers = True # 方案2:给自定义类添加序列化标识(二选一即可) Foo.__raven_class__ = "Foo" FooBar.__raven_class__ = "FooBar" store.initialize() class Foo(object): def __init__(self, name, key = None): self.name = name self.key = key class FooBar(object): def __init__(self, name, foo): self.name = name self.foo = foo with store.open_session() as session: foo = Foo("PyRyDB") session.store(foo) session.save_changes()
方法二:针对不同打包工具的配置调整
针对PyInstaller
使用以下命令打包,显式收集RavenDB的所有依赖并保留必要文件:
pyinstaller --onefile --collect-all ravendb --hidden-import ravendb.documents --hidden-import ravendb.documents.session your_script.py
--collect-all ravendb:确保RavenDB的所有相关文件都被打包进去--hidden-import:显式指定RavenDB的子模块,避免打包时遗漏
针对cx_Freeze
修改setup.py配置文件,包含RavenDB的所有依赖包:
from cx_Freeze import setup, Executable executables = [Executable("your_script.py")] setup( name="RavenDBApp", version="1.0", description="Application with RavenDB integration", executables=executables, options={ "build_exe": { "packages": ["ravendb", "ravendb.documents", "ravendb.documents.session"], "includes": ["your_script"] } } )
然后运行python setup.py build完成打包。
针对Auto PY to EXE
- 加载你的Python脚本后,切换到Hidden Imports标签,添加以下模块:
ravendbravendb.documentsravendb.documents.session
- 切换到Additional Files标签,添加RavenDB的安装目录(一般在
Python安装路径\Lib\site-packages\ravendb) - 保持其他默认配置,点击Convert .py to .exe完成打包
内容的提问来源于stack exchange,提问作者Sajad.Y
相关产品推荐
相关产品推荐

