AzureML调用register_pandas_dataframe报DatasetValidationError
AzureML register_pandas_dataframe 注册DataFrame报错排查
问题现象
调用register_pandas_dataframe方法注册pandas DataFrame时持续失败,公开渠道可查的AzureML相关参考资料少,且大量官方文档已废弃,逐行分析报错栈无法定位修复点。
使用极简测试样例复现代码如下:
df_temp = pd.DataFrame({'A' : [1,2,3], 'B' : [4,5,6]}) Dataset.Tabular.register_pandas_dataframe(df_temp, DATASTORE, "Test_dataset", description='Test', tags=None, show_progress=True)
执行后抛出核心报错为DatasetValidationError: Failed to validate the data. The Dataflow produced no records.,完整报错栈如下:
DataflowValidationError Traceback (most recent call last) File /anaconda/envs/azureml_py38/lib/python3.8/site-packages/azureml/data/dataset_error_handling.py:65, in _validate_has_data(dataflow, error_message) 64 try: ---> 65 dataflow.verify_has_data() 66 except (dataprep().api.dataflow.DataflowValidationError, 67 dataprep().api.errorhandlers.ExecutionError) as e: ... DatasetValidationError: DatasetValidationError: Message: Failed to validate the data. The Dataflow produced no records.| session_id=41857052-3cf1-4cf8-93ac-fe7ab1fd94e7 InnerException None ErrorResponse { "error": { "code": "UserError", "message": "Failed to validate the data.\nThe Dataflow produced no records.| session_id=41857052-3cf1-4cf8-93ac-fe7ab1fd94e7" } }
根因说明
从报错栈的方法调用逻辑可以看到,register_pandas_dataframe的内部执行流程是:
- 将传入的pandas DataFrame序列化为parquet临时文件
- 将parquet文件写入传入的目标数据存储
DATASTORE的自动生成路径 - 从该存储路径读取parquet文件生成TabularDataset
- 执行数据校验,确认数据集非空后完成注册
报错出在校验环节读不到任何数据,本质是前序的parquet写入环节异常,或者读取环节的权限/版本不匹配。
可落地修复方案
按优先级从高到低依次排查:
- 检查数据存储权限:当前运行环境(计算实例/作业进程)对目标
DATASTORE没有写入权限是最高发诱因。方法写入临时文件失败时不会提前抛出明确的写入错误,直到后续读数据校验才会报空记录错误。可以先单独测试往该数据存储上传一个本地小文件,确认读写权限正常后再运行注册逻辑。 - 修复SDK版本冲突:
azureml_py38环境默认预装的azureml-core和azureml-dataprep经常出现版本不兼容问题,新版本该注册方法存在已知的空校验bug。执行以下命令固定兼容版本,安装完成后重启内核再测试:
pip install --upgrade azureml-core==1.48.0 azureml-dataprep[pandas]==4.10.8
- 避免直接写入数据存储根目录:部分启用了分层命名空间/软删除规则的存储账号,直接往根目录写入临时parquet文件会出现文件不可见的问题。显式指定一个子目录作为写入目标即可,修改代码如下:
from azureml.data.datapath import DataPath # 显式指定写入到datastore下的dataset_temp子目录 target_path = DataPath(DATASTORE, "dataset_temp/") Dataset.Tabular.register_pandas_dataframe( df_temp, target=target_path, name="Test_dataset", description='Test', tags=None, show_progress=True )
- 绕开内置写入逻辑兜底:如果以上方案都不生效,可以跳过
register_pandas_dataframe的自动写入流程,手动序列化、上传文件后注册数据集,稳定性更高:
# 本地序列化DataFrame为parquet df_temp.to_parquet("./temp_data.parquet") # 手动上传到数据存储 DATASTORE.upload_files(["./temp_data.parquet"], target_path="manual_ds_upload/", overwrite=True) # 从已上传的parquet文件创建并注册数据集 from azureml.data.dataset_factory import TabularDatasetFactory ds = TabularDatasetFactory.from_parquet_files(path=(DATASTORE, "manual_ds_upload/temp_data.parquet")) registered_ds = ds.register(workspace=ws, name="Test_dataset", create_new_version=True)
内容的提问来源于stack exchange,提问作者Tim Anders
相关产品推荐
相关产品推荐

