Azure中从.py文件运行Databricks笔记本,解决模块跨内存空间调用问题
问题描述
在使用pytest测试Azure Databricks笔记本时,遇到模块加载的内存空间隔离问题:
- 在目标笔记本内,通过
%run指令加载自定义基类模块dbx_class后,可直接调用其方法:
%run ../dbx_class dbx_class.some_function() # 正常执行,模块已加载到当前内存空间
- 但使用
dbutils.notebook.run执行同一模块笔记本后,无法在当前上下文调用dbx_class:
dbutils.notebook.run('../dbx_class',0) # 执行成功,但模块未进入当前内存 dbx_class.some_function() # 报错:NameError: name 'dbx_class' is not defined
已知dbutils.notebook.run与%run运行在独立内存空间,需解决如何正确加载模块,以及是否可通过.py文件在当前内存空间运行该笔记本的问题。
解决方案
1. 直接使用%run加载模块
%run的核心特性就是将目标笔记本的代码加载到当前内存空间,完全适配你的测试场景。如果不需要异步执行或独立运行环境,直接在测试代码中保留%run ../dbx_class即可,这是最直接的解决方式。
2. 将模块转为.py文件并通过Python导入加载
若需要从.py文件加载,可按以下步骤操作:
- 提取
dbx_class笔记本中的代码,保存为标准Python文件(如dbx_class.py),上传到Databricks工作区对应路径(如../dbx_class.py)。 - 在测试笔记本中通过以下方式导入:
import sys # 添加模块所在目录到Python路径 sys.path.append("/Workspace/your/path/to/dbx_class_folder") from dbx_class import some_function # 直接调用方法 some_function()
如果已将模块目录配置到Databricks全局Python路径,可简化为直接导入:
from dbx_class import some_function
3. 若必须使用dbutils.notebook.run,通过返回结果间接使用
如果业务场景要求必须用dbutils.notebook.run,可修改dbx_class笔记本,将需要的功能结果序列化后返回:
- 修改
dbx_class笔记本末尾:
import json # 执行目标方法并序列化结果 result = some_function() dbutils.notebook.exit(json.dumps(result))
- 在调用方解析返回结果:
import json output = dbutils.notebook.run('../dbx_class', 0) result = json.loads(output) # 使用返回的结果数据
注意:这种方式仅能获取方法执行结果,无法将模块本身加载到当前内存空间。
4. 适配Databricks测试框架
在pytest测试场景中,可使用databricks-connect或pytest-databricks等官方工具,这些工具能模拟笔记本的实际运行环境,支持%run的内存加载逻辑,让测试更贴近生产环境的执行方式。
内容的提问来源于stack exchange,提问作者Ryan Wall
相关产品推荐
相关产品推荐

