如何从 TXT 文件中提取 JSON?
How to ingest JSON from TXT file?
问题是无法获取 TXT,因为它是
SELECT to_jsonb(file_get_contents('/tmp/test.json'))
returns 不是 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;
我使用 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 数据
中找到的元素定义列
它已经是 JSON 格式,您只需投射它:
SELECT file_get_contents('/tmp/test.json')::jsonb
"to_json" 的文档说
For any scalar type other than a number, a Boolean, or a null value,
the text representation will be used, in such a fashion that it is a
valid json or jsonb value.
换句话说,它会进行必要的转义和引用,将您的文件转换为单个 JSON 值。不是 JSON 对象,只是一个值。所以 "to_json" 是错误的工具。
问题是无法获取 TXT,因为它是
SELECT to_jsonb(file_get_contents('/tmp/test.json'))
returns 不是 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;
我使用 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 数据
中找到的元素定义列它已经是 JSON 格式,您只需投射它:
SELECT file_get_contents('/tmp/test.json')::jsonb
"to_json" 的文档说
For any scalar type other than a number, a Boolean, or a null value, the text representation will be used, in such a fashion that it is a valid json or jsonb value.
换句话说,它会进行必要的转义和引用,将您的文件转换为单个 JSON 值。不是 JSON 对象,只是一个值。所以 "to_json" 是错误的工具。