postgres存储对json

时间:2019-06-03 18:47:08

标签: json postgresql reference

可以使用json数据类型将json存储在postgres中。查看本教程以获取简介:http://www.postgresqltutorial.com/postgresql-json/

考虑我将以下json存储在这样的字段中:

{
  "address": {
    "street1": "123 seasame st"
  }
}

我想要一个单独存储对street字段的引用。例如,我可能有另一个对象正在使用此json结构中的数据,并希望存储对其数据来源的引用。也许是这样的:

class Product():
    __tablename__ = 'Address'

    street_1 = Column(String)
    data_source = ?

现在,我可以将data_source用作字符串,并仅存储address.street之类的名称空间,但是如果我这样做的话,postgres并不知道这意味着什么。在查询中使用它意味着解析字符串和其他低效的东西。 Postgres是否支持引用存储在json数据结构中的字段?

这个问题与JSON foreign keys in PostgreSQL有关,但是在这种情况下,我不一定想要建立fk关系。我只想创建一个引用,它不一定以fk的方式强制执行。

更新:

更清楚地说,我想在另一个属性上引用json结构中某些内容的位置,并将该引用存储在列中。在下面的代码中,Address.data_source是一个引用街道数据的位置(例如address.street1

class Address():
    __tablename__ = 'Address'

    street_1 = Column(String)
    sample_id = Column(Integer, ForeignKey('DataSample.uid'))

    data_source = ?

class DataSample():
    __tablename__ = 'DataSample'
    uid = Column(Integer, primary_key=True)
    data = Column(JSONB)


body = {
  "address": {
    "street1": "123 seasame st"
  }
}

datasample = DataSample(data=body)
address = Address(street_1=datasample.data['address']['street_1'], 
                  sample_id=datasample.uid,
                  data_source=?)

1 个答案:

答案 0 :(得分:1)

正如已阐明的那样,问题正在寻找一种方法来灵活地指定特定记录的JSON对象内的路径。密钥在普通列中处理。 JSONB字段的约束为not available,并且不支持在JSON对象中指定路径。

我在SQL Fiddle中使用PostgreSQL 9.6进行了以下工作:

CREATE TABLE datasample (
  id integer PRIMARY KEY,
  data jsonb
);
CREATE TABLE address (
  id integer PRIMARY KEY,
  street_1 text,
  sample_id integer REFERENCES datasample (id),
  data_source text
);
INSERT INTO datasample(id, data) 
VALUES (1, '{"address":{"street_1": "123 seasame st"}}');
INSERT INTO address(id,street_1, sample_id, data_source) 
VALUES (1,'123 seasame st',1,'datasample.data->''address''->>''street''');

典型的街道地址查找(需要检索street_1)类似于:

SELECT datasample.data->'address'->>'street_1' 
FROM datasample 
WHERE id=1;

没有特殊的postgres类型来标识列。字符串是最接近的可用字符串,您将需要检索字符串(或字符串数​​组,或包含字符串的对象,如果其中之一简化了解析),并使用它来构建查询。在第一个代码块中,我以 as 形式存储了查询的(转义的)片段-'datasample.data->''address''->>''street'''。尽管更长,但只需要检索和转义就可以在新的自定义查询中使用。我没有找到在相同的SQL语句中将该字符串用作片段的方法,尽管可以将其与其他文本位组合以形成可以通过EXECUTE运行的完整语句。