U-Sql中的文件存在和异常处理
File Exists and Exception Handling in U-Sql
两个问题
EXTRACT前如何判断文件是否存在?
我们有每天为目录数据生成新输入文件的场景。我们需要将新输入与 d-1 文件合并。在合并之前我们要确保新的输入文件存在于源位置
u-sql 支持 try...catch 块吗?
关于检查文件是否存在。我们最近发布了一个编译时 IF
语句,它确实可以检查分区是否存在(以及文件和表等其他对象在路线图上)。
该功能发布后(在回答此问题时仍有一两次刷新)它可能看起来像(语法可能会更改):
IF FILE.EXISTS("/mydir/myfile.csv") THEN
@data = EXTRACT ... FROM "/mydir/myfile.csv" USING ...;
...
@jobstate = SELECT * FROM (VALUES("job completed")) AS T(status);
ELSE
@jobstate = SELECT * FROM (VALUES("file not ready. Job not executed.")) AS T(status);
END;
OUTPUT @jobstate TO "/jobs/myjobstate.csv" USING Outputters.Csv();
您也可以提供名称作为参数。请让我知道这是否适用于您的场景。
另一种替代方法是使用文件集语法,尤其是当您想使用动态值来确定进程时。这只会创建一个空行集:
@data = EXTRACT ..., date DateTime
FROM "/mydir/{date:yyyy}/{date:MM}/{date:dd}/data.csv"
USING ...;
@data = SELECT * FROM @data WHERE date == DateTime.Now.AddDays(-1);
... // continue processing @data that is empty if yesterday's file is not yet there
话虽如此,您可能想要检查您的作业编排框架(例如 ADF),这可能是在提交作业之前检查是否存在的更好的地方。
至于 try catch 块:U-SQL 本身是一种脚本级可优化的声明性语言,其中计划在整个脚本的运行时生成和优化。因此,目前无法提供动态 TRY-CATCH,因为它会严重影响优化脚本的能力(例如,您不能将谓词或列修剪移到 try-catch 块之外)。此外 TRY/CATCH 可能会导致一些代码非常难以理解和调试,特别是如果它用于在其他声明性环境中模仿过程性工作流。
但是,如果您需要捕获 C# 运行时错误,则可以在 C# 函数中使用 try/catch 而不会出现问题。
FILE.EXISTS()
在本地执行时总是 returns True
。但是,它在针对 Azure Data Lake 执行时有效。
尝试了 MSDN example 和以下 returns 正确,正确
DECLARE @filepath_good = "/Samples/Data/SearchLog.tsv";
DECLARE @filepath_bad = "/Samples/Data/zzz.tsv";
@result =
SELECT FILE.EXISTS(@filepath_good) AS exists_good,
FILE.EXISTS(@filepath_bad) AS exists_bad
FROM (VALUES (1)) AS T(dummy);
OUTPUT @result
TO "/Output/FileExists.txt"
USING Outputters.Csv();
我有 Visual Studio 版本 2.2.5000.0
的 Microsoft Azure Data Lake Tools
两个问题
EXTRACT前如何判断文件是否存在? 我们有每天为目录数据生成新输入文件的场景。我们需要将新输入与 d-1 文件合并。在合并之前我们要确保新的输入文件存在于源位置
u-sql 支持 try...catch 块吗?
关于检查文件是否存在。我们最近发布了一个编译时 IF
语句,它确实可以检查分区是否存在(以及文件和表等其他对象在路线图上)。
该功能发布后(在回答此问题时仍有一两次刷新)它可能看起来像(语法可能会更改):
IF FILE.EXISTS("/mydir/myfile.csv") THEN
@data = EXTRACT ... FROM "/mydir/myfile.csv" USING ...;
...
@jobstate = SELECT * FROM (VALUES("job completed")) AS T(status);
ELSE
@jobstate = SELECT * FROM (VALUES("file not ready. Job not executed.")) AS T(status);
END;
OUTPUT @jobstate TO "/jobs/myjobstate.csv" USING Outputters.Csv();
您也可以提供名称作为参数。请让我知道这是否适用于您的场景。
另一种替代方法是使用文件集语法,尤其是当您想使用动态值来确定进程时。这只会创建一个空行集:
@data = EXTRACT ..., date DateTime
FROM "/mydir/{date:yyyy}/{date:MM}/{date:dd}/data.csv"
USING ...;
@data = SELECT * FROM @data WHERE date == DateTime.Now.AddDays(-1);
... // continue processing @data that is empty if yesterday's file is not yet there
话虽如此,您可能想要检查您的作业编排框架(例如 ADF),这可能是在提交作业之前检查是否存在的更好的地方。
至于 try catch 块:U-SQL 本身是一种脚本级可优化的声明性语言,其中计划在整个脚本的运行时生成和优化。因此,目前无法提供动态 TRY-CATCH,因为它会严重影响优化脚本的能力(例如,您不能将谓词或列修剪移到 try-catch 块之外)。此外 TRY/CATCH 可能会导致一些代码非常难以理解和调试,特别是如果它用于在其他声明性环境中模仿过程性工作流。
但是,如果您需要捕获 C# 运行时错误,则可以在 C# 函数中使用 try/catch 而不会出现问题。
FILE.EXISTS()
在本地执行时总是 returns True
。但是,它在针对 Azure Data Lake 执行时有效。
尝试了 MSDN example 和以下 returns 正确,正确
DECLARE @filepath_good = "/Samples/Data/SearchLog.tsv";
DECLARE @filepath_bad = "/Samples/Data/zzz.tsv";
@result =
SELECT FILE.EXISTS(@filepath_good) AS exists_good,
FILE.EXISTS(@filepath_bad) AS exists_bad
FROM (VALUES (1)) AS T(dummy);
OUTPUT @result
TO "/Output/FileExists.txt"
USING Outputters.Csv();
我有 Visual Studio 版本 2.2.5000.0
的 Microsoft Azure Data Lake Tools