Snowflake 中的断言

Mar*_*Roy 2 sql assert assertion snowflake-cloud-data-platform

有没有办法在雪花中执行断言?

基本上,我正在尝试进行一些测试/TDD,并且我想要一种类似于其他所有语言中的断言的机制:

  • 如果断言成功,则返回 true(和/或打印成功消息)。
  • 如果断言失败,则会引发异常。

Mar*_*Roy 5

我找不到在 Snowflake 中执行断言的任何方法,所以我最终使用 JavaScript UDF 构建了自己的断言:

CREATE OR REPLACE FUNCTION assert(VALUE STRING, TEST STRING)
  RETURNS STRING
  LANGUAGE JAVASCRIPT
AS
$$
  if (VALUE === TEST) {
    return `True ('${VALUE}' = '${TEST}')`;
  } else {
    throw `Assertion failed: '${VALUE}' != '${TEST}'`
  }
$$
;

/* Tests should all return true */
SELECT assert(true, true);
SELECT assert('string', 'string');
SELECT assert(123, 123);
SELECT assert('123', 123);

/* Tests should all fail and throw exceptions */
SELECT assert(true, false);
SELECT assert('string1', 'string2');
SELECT assert(12345, 54321);
SELECT assert('123', 321);
Run Code Online (Sandbox Code Playgroud)


Mar*_*Roy 0

此后,我们不再使用assertUDF,而是直接在 SQL 中比较预期值和实际值。它的优点是避免从 SQL 到 JavaScript 的类型转换,因此更加准确。

SELECT
  'something' AS actual,
  'something_else' AS expected
FROM ...
WHERE actual != expected
   AND ('~\n\nERROR: unexpected result: ' || actual
     || '\n\nExpected: ' || expected || '\n\n~');
Run Code Online (Sandbox Code Playgroud)

在聚合值的情况下,我们只需使用HAVING代替WHERE

如果两个值确实不相等,则条件AND将始终失败(因为它不是布尔值),但如果两个值相等,则布尔逻辑将忽略它(因此第一个条件失败,从而不返回任何结果)。

两者~是简单的分隔符。也可以是其他任何东西。

在 Snowsight 中,错误的输出如下所示:

在此输入图像描述

在 DBT 中,输出如下所示:

在此输入图像描述