【问题标题】:'cannot extract element from a scalar' when order by id is DESC当 id 为 DESC 时,“无法从标量中提取元素”
【发布时间】:2020-11-14 02:13:20
【问题描述】:

我有一个 PostgreSQL 9.3.10 数据库,一个包含 15842 条记录的表,并使用 Intellij 进行查询。 我想从 JSON 列(名为“数据”)中查询一些最近的数据。

我的查询就是这么简单:

select data->'header'
from some_table
order by id desc

问题是我得到了:

[22023] 错误:无法从标量中提取元素

当我使用desc 命令时。当我使用asc 时,查询不会失败,并且至少收到前 500 条记录。

对我来说,最近的一些记录可能包含无效的 JSON。如果是这样,我怎样才能忽略不良记录并仍然使用DESC 排序执行查询?或者如何识别损坏的 JSON 记录?

我也认为它可能是由空数据引起的,但select * from table where data is null 没有显示任何结果。

UPD:“数据”列的类型是json。我发现有些行将 json 数据序列化为字符串(由于后端错误)。所以不是普通的 json object: {} 值是一个带引号的对象 string "{}"。由以下查询检测到:select data from some_table where data::text not like '{%'

【问题讨论】:

    标签: sql json postgresql where-clause postgresql-9.3


    【解决方案1】:

    您对问题的描述表明 data 列未使用正确的数据类型创建。如果是jsonjsonb,则错误数据将在插入时被拒绝。

    我认为 Postgres 没有内置函数来检查 JSON 字符串的有效性。您需要创建一个,例如:

    create or replace function is_jsonb(js text)
        returns boolean
    as $$
    begin
        return (js::jsonb is not null);
    exception 
        when others then return false;  
    end;
    $$
    language plpgsql;
    

    然后你可以在查询中使用它:

    select *
    from mytable
    where not is_jsonb(data);
    

    根据data 的数据类型,可能需要额外的转换,例如:

    where not is_jsonb(data::text);
    

    【讨论】:

    • 列数据类型为json。现在我看到问题在于某些行已将 json 序列化为字符串 ("{}")。它仍然是 JSON,但是字符串而不是我期望的对象
    • @Kirill:也许你想要:where not is_jsonb((data->'header')::text)?
    【解决方案2】:

    问题是由 ActiveRecord 版本更新引起的,它导致接收 to_json 的 Ruby 对象被显式写入为单个字符串,这也是一个有效的 JSON 数据(Postgres 称之为:错误消息中的“标量”)。 这就是为什么只在使用by id desc 的查询中出现错误的原因(仅适用于在 ActiveRecord 更新后创建的新记录)。以下是关于 ActiveRecord 更改的说明:https://github.com/rails/rails/commit/835246e622dc0431af3cb951db22ef78876006af

    所以不是{"header": "value"},而是写成"{\"header\": \"value\"}"。 使用以下查询修复了数据库:

    update some_table 
    set data = REPLACE(TRIM(BOTH '"' from data::text), '\"', '"')::JSON 
    where data::text like '"%';
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-06
      • 2017-01-07
      • 1970-01-01
      • 2019-07-21
      • 1970-01-01
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多