【问题标题】:PostgreSQL function ON INSERT, insert JSON values to another tablePostgreSQL 函数 ON INSERT,将 JSON 值插入另一个表
【发布时间】:2020-11-16 17:58:44
【问题描述】:

我正在尝试在 PostgreSQL 中编写一个函数,该函数在插入 Cloudant 文档时通过侦听 Cloudant 接收记录(我想将其设为 lambda,但现在它是一个节点进程)。

我正在获取 Cloudant id 和完整文档并将其插入到 case_raw 表中,其中包含以下列:char(32) id 和 json 类型 raw_json

CREATE TABLE report_db.case_raw
(
    doc_id character(32) NOT NULL PRIMARY KEY,
    raw_json jsonb NOT NULL
)

从 Cloudant 到 Postgres 的努力是为了让我可以对来自边缘设备的 JSON 形式的数据进行复杂的连接等。

这是 Cloudant 文档的示例,我在 id 列中使用了相同的 id,它将被插入到 raw_json 中。

{
    "name": {
        "id": "4e1e3425ef49b3b028683a5cb06ca585",
        "doc": {
            "_id": "4e1e3425ef49b3b028683a5cb06ca585",
            "_rev": "1-feae33bee0b773c7d130b1dd6fb42869",
            "doc_type": "standard",
            "location": {
                "carrier": "AT&T",
                "mobileCountryCode": 123,
                "mobileNetworkCode": 456
            }
        }
    }
}

现在,我想制作一个 trigger,它为每一行 ON INSERT 调用一个 函数

但是,我马上就要挂断电话了。我已经尝试了所有我能想到的方法,包括:WITH、嵌套 SELECT、to_json、强制转换 ::json,我敢打赌这很简单,但为什么我不能(似乎)不使用 JSON 运算符?

我可以直接查询记录并从这条记录中获取我想要的数据,例如(以两种不同的方式获取相同的东西):

SELECT * FROM case_raw WHERE raw_json->'name'->'doc'->'location'->>'carrier' = 'AT&T';

SELECT * FROM case_raw WHERE raw_json @> '{"name":{"doc": {"location": { "carrier": "AT&T"}}}}'

但是,就我的一生而言,我无法进入 JSON。我已经阅读了至少 20 篇文章、PG 文档、PG 教程,但没有找到任何可以推动我前进的东西。非常感谢任何见解。在这里,我大大减少了使用with 等的尝试。PGAdmin 在->'name' 上报告错误。

CREATE OR REPLACE FUNCTION parse_raw ()
RETURNS trigger AS '
BEGIN
  -- We have a lot more values to insert, but PG does not seem to like the syntax of the following:
  INSERT INTO report_db.location_master VALUES (NEW.raw_json->'name'->'doc'->'location'->>'carrier');
  RETURN NEW;
END' LANGUAGE 'plpgsql';

-- setup on before insert trigger to parse into tables
CREATE TRIGGER parse_raw_trigger
BEFORE INSERT ON report_db.case_raw
FOR EACH ROW
EXECUTE PROCEDURE parse_raw();

【问题讨论】:

  • @a_horse_with_no_name 我在 Postgres 的很​​多帖子上都看到了你的名字,我真的很希望你能看到这个!我添加了一个与location 匹配的属性结构todo 的示例。提前感谢您的任何见解!

标签: postgresql-json


【解决方案1】:

您正在将字符串嵌入到字符串中。所以对于嵌入的'name',单引号需要是escaped。所以你基本上有' ... 'name' ... ,它不是一个有效的字符串常量。应该是' ... ''name'' ...'

为了更容易,通常的方法是用dollar quotes包装整个函数体(字符串)

在 INSERT 语句中始终限定目标列也是一种很好的编码习惯。

CREATE OR REPLACE FUNCTION parse_raw ()
RETURNS trigger AS 
$body$ --<< replaces the '
BEGIN
 -- We have a lot more values to insert, but PG does not seem to like the syntax of the following:
 INSERT INTO report_db.location_master (carrier) VALUES (NEW.raw_json->'name'->'doc'->'location'->>'carrier');
 RETURN NEW;
END;
$body$ --<< replaces the '
LANGUAGE plpgsql;

【讨论】:

  • 太棒了!遵循有关合格目标列的建议也使所有内容都更易于阅读。
猜你喜欢
  • 1970-01-01
  • 2013-08-16
  • 2011-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多