【问题标题】:How to ingest JSON from TXT file?如何从 TXT 文件中提取 JSON?
【发布时间】:2019-12-03 19:04:35
【问题描述】:

问题不在于获取TXT,因为它是

SELECT to_jsonb(file_get_contents('/tmp/test.json'))

返回的不是 JSON 对象而是字符串...即使使用 replace(txt,E'\n',' ') 它也不起作用。如何规范化字符串并将其真正转换为 JSON?

PS:我正在使用 JSONb,它必须是 JSON 来进行摄取。


注意事项

json文件/tmp/test.json:

[
    {
      "foo": "etc",
      "bar": "etc",
      "x": 123
    },
    {
      "foo": "aaa",
      "bar": "bbb",
      "x": 456
    }
]

我正在使用 UBUNTU 18 LTS、PostgreSQL v12 和 linux 标准 TXT 中的文件。终端命令file -i /tmp/test.json 说这一切都很好,“text/plain; charset=utf-8”。

仅将全文加载到一个字段中(使用 COPY FROM 似乎不可能),PostgreSQL 很丑,但是这个功能经过测试并且可靠:

CREATE EXTENSION PLpython3U;
CREATE or replace FUNCTION file_get_contents(p_file text) RETURNS text AS $$
   import os.path
   if not os.path.isfile(args[0]):
       return None
   with open(args[0],"r") as content_file:
       content = content_file.read()
   return content
$$ LANGUAGE PLpython3U;

【问题讨论】:

    标签: json postgresql data-ingestion


    【解决方案1】:

    使用 postgresql,我将您的文件保存在我的 /tmp 目录中。

    要读取文件,如果文件在你的postgresql服务器上,你可以使用pg_read_file()

    为了模拟您的场景,我尝试了以下方法:

    方法 1 (json_array_elements_text):

    SELECT JSON_ARRAY_ELEMENTS_TEXT(
           REPLACE(PG_READ_FILE('/tmp/teste.txt'), E'\n', '')::JSON);
    

    这一系列的功能和你使用的很相似,只是pg_read_file是读取服务器上的文件,json_array_elements_text

    结果是:

                      json_array_elements_text                  
    ------------------------------------------------------------
     {      "foo": "etc",      "bar": "etc",      "x": 123    }
     {      "foo": "aaa",      "bar": "bbb",      "x": 456    }
    (2 rows)
    

    方法 2 (json_to_recordset):

    select * from json_to_recordset(replace(pg_read_file('/tmp/teste.txt'), E'\n', '')::json) as ("foo" varchar, "bar" varchar, "x" int);
     foo | bar |  x  
    -----+-----+-----
     etc | etc | 123
     aaa | bbb | 456
    (2 rows)
    

    结果与第一个示例相似,但在这种方法中,我们根据原始 json 数据中的元素定义列

    【讨论】:

    • 谢谢@William。 @jjanes 的答案更易于阅读,但您是第一个并展示了 PG_READ_FILE(),这似乎比自定义函数更好且更可靠。
    【解决方案2】:

    它已经是 JSON 格式了,你只需要转换它:

    SELECT file_get_contents('/tmp/test.json')::jsonb
    

    “to_json”的文档说

    对于除数字、布尔值或空值以外的任何标量类型, 文本表示将被使用,其方式是 有效的 json 或 jsonb 值。

    换句话说,它执行将文件转换为单个 JSON 值所需的转义和引用。不是 JSON 对象,只是一个值。所以“to_json”是错误的工作工具。

    【讨论】:

    • 谢谢,是吗。但是原始文件不在“all in one line” JSON 中...这是个大问题,并且没有内部 PostgreSQL 工具来清理行和空格(存在吗?)...我正在使用终端 jq --compact-output . original.json > sanitized.json跨度>
    • 这是操作系统特有的问题吗?对我来说,它只适用于 Linux。如果空格不重要(即引号之外),它将被忽略。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-16
    • 1970-01-01
    相关资源
    最近更新 更多