Kev*_*n S 9 postgresql amazon-redshift
我正在尝试在redshift中运行我正在选择使用的查询json_extract_path_text.不幸的是,此数据库列中的某些JSON条目无效.  
会发生什么: 当查询遇到无效的JSON值时,它会因"JSON解析错误"而停止.
我想要的:忽略该列中包含无效JSON的所有行,但返回可以解析JSON的任何行.
为什么我不能让它做我想做的事情:我认为我不理解Redshift/Postgres中的错误处理.应该可以简单地跳过任何产生错误的行,但我尝试输入EXEC SQL WHENEVER SQLERROR CONTINUE(基于Postgres文档)并在"或接近SQLERROR"时出现"语法错误".
dvm*_*lls 10
创建一个python UDF:
create or replace function f_json_ok(js varchar(65535)) 
returns boolean
immutable
as $$
    if js is None: 
        return None
    import json
    try:
        json.loads(js)
        return True
    except:
        return False
$$ language plpythonu
像这样使用它:
select *
from schema.table
where 'DesiredValue' = 
    case 
        when f_json_ok(json_column) then json_extract_path_text(json_column, 'Key') 
        else 'nope' 
    end 
编辑:似乎Redshift 只支持 Python UDF,所以这个答案不起作用。我将把这个答案留在这里供后代使用(如果有人发现了这个没有使用 Redshift 的人)。
潜在相关:这是一个 plpgsql 函数,它将尝试解码 JSON 并在失败时返回默认值:
CREATE OR REPLACE FUNCTION safe_json(i text, fallback json) RETURNS json AS $$
BEGIN
    RETURN i::json;
EXCEPTION
    WHEN others THEN
        RETURN fallback;
END;
$$ LANGUAGE plpgsql IMMUTABLE RETURNS NULL ON NULL INPUT;
然后你可以像这样使用它:
SELECT
    …
FROM (
    SELECT safe_json(my_text, '{"error": "invalid JSON"}'::json) AS my_json
    FROM my_table
) as x
保证您始终拥有有效的 JSON
我假设 JSON 数据实际上存储在 TEXT 列而不是 JSON 列中(否则您一开始就无法在其中存储非 JSON)。
如果数据存在某种模式,允许您创建一个正则表达式来检测有效行或无效行,那么您可以使用 CASE 语句。例如:
SELECT CASE
    WHEN mycol !~ 'not_json' THEN json_extract_path_text(mycol, ....)
    ELSE NULL
END AS mystuff
...
将 not_json 替换为检测非 JSON 格式值的正则表达式。
这可能实用也可能不实用,具体取决于数据的格式。
根据这个问题的答案,显然可以使用一些正则表达式实现来完全验证任意 JSON 数据,但可惜不是 postgresql 使用的那个。
| 归档时间: | 
 | 
| 查看次数: | 9539 次 | 
| 最近记录: |