我有JSON
一个文件如下:
[xyz@innolx20122 ~]$ cat cgs_test.json
{"technology":"AAA","vendor":"XXX","name":"RBNI","temporal_unit":"hour","regional_unit":"cell","dataset_metadata":"{\"name\": \"RBNI\", \"temporal_unit\": \"hour\", \"technology\": \"LTE\", \"is_dimension\": false, \"timestamp_column_pattern\": \"yyyyMMddHHmmss\", \"data_type\": \"PM\", \"source_name\": \"RBNI\", \"intervals_epoch_seconds\": [[1609941600, 1609945200]], \"identifier_column_names\": [\"CELLID\", \"CELLNAME\", \"radio_frequency_band\", \"ENODEBID\", \"ENODEBNAME\", \"SBNID\", \"SITEID\", \"SITENAME\", \"CLUSTER_PRIORITY\", \"CP_SITE\", \"IBC\", \"NETWORK_TIER\", \"SITE_TYPE\", \"T3_FLAG\", \"CLUSTERID\", \"CLUSTERNAME\", \"REGION\", \"NETWORK\"], \"vendor\": \"ZTE\", \"timestamp_column_name\": \"COLLECTTIME\", \"regional_unit\": \"cell\"}","rk":1}
{"technology":"AAA","vendor":"XXX","name":"RRCADD","temporal_unit":"hour","regional_unit":"cell","dataset_metadata":"{\"name\": \"RRCADD\", \"temporal_unit\": \"hour\", \"technology\": \"AAA\", \"is_dimension\": false, \"timestamp_column_pattern\": \"yyyyMMddHHmmss\", \"data_type\": \"PM\", \"source_name\": \"RRCADD\", \"intervals_epoch_seconds\": [[1609941600, 1609945200]], \"identifier_column_names\": [\"CELLID\", \"CELLNAME\", \"radio_frequency_band\", \"ENODEBID\", \"ENODEBNAME\", \"SBNID\", \"SITEID\", \"SITENAME\", \"CLUSTER_PRIORITY\", \"CP_SITE\", \"IBC\", \"NETWORK_TIER\", \"SITE_TYPE\", \"T3_FLAG\", \"CLUSTERID\", \"CLUSTERNAME\", \"REGION\", \"NETWORK\"], \"vendor\": \"XXX\", \"timestamp_column_name\": \"COLLECTTIME\", \"regional_unit\": \"cell\"}","rk":1}
Run Code Online (Sandbox Code Playgroud)
我已将其加载到一个临时表中:
create table temp_json (values text);
\copy temp_json from '/home/xyz/cgs_test.json';
Run Code Online (Sandbox Code Playgroud)
现在我想将此数据提取到单独的列中:
technology
vendor
name
temporal_unit
regional_unit
dataset_metadata
rk
Run Code Online (Sandbox Code Playgroud)
dataset_metadata
是一个 JSON 列,其他列是字符串。
为了回答这个问题,我所做的是以下(请参阅此处的小提琴):
这对我来说是一次非常好的学习体验(顺便说一句,+1)所以我将按照我的逻辑步骤进行操作,希望这会对您有所帮助-但我确实是为自己做的:-)
第1步:
CREATE TABLE temp_1
(
json_input TEXT NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
第2步:
用你的两条记录填充它。但是,您的两个记录不是正确的 JSON - 它们[
在开头和]
结尾都需要一个,以便它们成为正确的 JSON - 所以,我INSERT
在流程的一开始就将它们放入了- 我离开了由读者来试验如果你把它们放在外面会发生什么——你可以在这个过程的后期把它们放进去——见下文。
可能有一种方法不必使用不同的JSON
功能来执行此操作- 恐怕超出我的工资等级 - 但我很感激任何改进建议。
INSERT INTO temp_1 VALUES -- strings copied from the question
('{"technology":"AAA","vendor":"XXX","name":"RBNI","temporal_unit":"hour","regional_unit":"cell","dataset_metadata":"{\"name\": \"RBNI\", \"temporal_unit\": \"hour\", \"technology\": \"LTE\", \"is_dimension\": false, \"timestamp_column_pattern\": \"yyyyMMddHHmmss\", \"data_type\": \"PM\", \"source_name\": \"RBNI\", \"intervals_epoch_seconds\": [[1609941600, 1609945200]], \"identifier_column_names\": [\"CELLID\", \"CELLNAME\", \"radio_frequency_band\", \"ENODEBID\", \"ENODEBNAME\", \"SBNID\", \"SITEID\", \"SITENAME\", \"CLUSTER_PRIORITY\", \"CP_SITE\", \"IBC\", \"NETWORK_TIER\", \"SITE_TYPE\", \"T3_FLAG\", \"CLUSTERID\", \"CLUSTERNAME\", \"REGION\", \"NETWORK\"], \"vendor\": \"ZTE\", \"timestamp_column_name\": \"COLLECTTIME\", \"regional_unit\": \"cell\"}","rk":1}'),
('{"technology":"AAA","vendor":"XXX","name":"RRCADD","temporal_unit":"hour","regional_unit":"cell","dataset_metadata":"{\"name\": \"RRCADD\", \"temporal_unit\": \"hour\", \"technology\": \"AAA\", \"is_dimension\": false, \"timestamp_column_pattern\": \"yyyyMMddHHmmss\", \"data_type\": \"PM\", \"source_name\": \"RRCADD\", \"intervals_epoch_seconds\": [[1609941600, 1609945200]], \"identifier_column_names\": [\"CELLID\", \"CELLNAME\", \"radio_frequency_band\", \"ENODEBID\", \"ENODEBNAME\", \"SBNID\", \"SITEID\", \"SITENAME\", \"CLUSTER_PRIORITY\", \"CP_SITE\", \"IBC\", \"NETWORK_TIER\", \"SITE_TYPE\", \"T3_FLAG\", \"CLUSTERID\", \"CLUSTERNAME\", \"REGION\", \"NETWORK\"], \"vendor\": \"XXX\", \"timestamp_column_name\": \"COLLECTTIME\", \"regional_unit\": \"cell\"}","rk":1}');
Run Code Online (Sandbox Code Playgroud)
然后,按如下方式将字符串转换为 JSON - 这可以批量完成:
--
-- This is to turn the "ordinary" strings into JSON per record. If this isn't
-- done, the process will fail further down. Will work for an arbitrary number
-- of records
--
UPDATE temp_1
SET json_input = '[' || json_input || ']';
Run Code Online (Sandbox Code Playgroud)
第 3 步:
创建另一个表:
CREATE TABLE temp_2
(
final_json JSON NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
第四步:
通过以下方式填充:
INSERT INTO temp_2 SELECT json_input::JSON FROM temp_1;
Run Code Online (Sandbox Code Playgroud)
该::JSON
投是必要的,否则INSERT
就会失败,因为json_input
是类型的TEXT
。
然后,清除“temp_1”:
--
-- Clear down temp_1.
-- This is needed for next batch, otherwise you'll have strings beginning
-- with '[[' and then '[[[' (endings same with multiple ']'s) and so on!
--
DELETE FROM temp_1;
Run Code Online (Sandbox Code Playgroud)
第 5 步:
创建一个表来保存数据:
CREATE TABLE json_table
(
technology TEXT,
vendor TEXT,
name TEXT,
temporal_unit TEXT,
regional_unit TEXT,
dataset_metadata JSON,
rk SMALLINT
);
Run Code Online (Sandbox Code Playgroud)
第 6 步:
从这里,我获得了这个方法来填充表格:
INSERT INTO json_table
SELECT (json_populate_recordset(null::json_table, final_json)).* FROM temp_2;
Run Code Online (Sandbox Code Playgroud)
小提琴中显示了另一种方式 - 从这里- YMMV?
第 7 步 - 最后检查:
SELECT * FROM json_table;
Run Code Online (Sandbox Code Playgroud)
结果:
technology vendor name temporal_unit regional_unit dataset_metadata rk
AAA XXX RBNI hour cell "{\"name\": \"RBNI\", \"temporal_unit\": \"hour\", \"technology\": \"LTE\", \"is_dimension\": false, \"timestamp_column_pattern\": \"yyyyMMddHHmmss\", \"data_type\": \"PM\", \"source_name\": \"RBNI\", \"intervals_epoch_seconds\": [[1609941600, 1609945200]], \"identifier_column_names\": [\"CELLID\", \"CELLNAME\", \"radio_frequency_band\", \"ENODEBID\", \"ENODEBNAME\", \"SBNID\", \"SITEID\", \"SITENAME\", \"CLUSTER_PRIORITY\", \"CP_SITE\", \"IBC\", \"NETWORK_TIER\", \"SITE_TYPE\", \"T3_FLAG\", \"CLUSTERID\", \"CLUSTERNAME\", \"REGION\", \"NETWORK\"], \"vendor\": \"ZTE\", \"timestamp_column_name\": \"COLLECTTIME\", \"regional_unit\": \"cell\"}" 1
AAA XXX RRCADD hour cell "{\"name\": \"RRCADD\", \"temporal_unit\": \"hour\", \"technology\": \"AAA\", \"is_dimension\": false, \"timestamp_column_pattern\": \"yyyyMMddHHmmss\", \"data_type\": \"PM\", \"source_name\": \"RRCADD\", \"intervals_epoch_seconds\": [[1609941600, 1609945200]], \"identifier_column_names\": [\"CELLID\", \"CELLNAME\", \"radio_frequency_band\", \"ENODEBID\", \"ENODEBNAME\", \"SBNID\", \"SITEID\", \"SITENAME\", \"CLUSTER_PRIORITY\", \"CP_SITE\", \"IBC\", \"NETWORK_TIER\", \"SITE_TYPE\", \"T3_FLAG\", \"CLUSTERID\", \"CLUSTERNAME\", \"REGION\", \"NETWORK\"], \"vendor\": \"XXX\", \"timestamp_column_name\": \"COLLECTTIME\", \"regional_unit\": \"cell\"}" 1
Run Code Online (Sandbox Code Playgroud)
一些想法:
您的dataset_metadata
字段似乎不是“正确的”JSON - 也许合适REGEXP_REPLACE
和/或CAST
可能合适?我不知道您获取/home/xyz/cgs_test.json
文件的过程 - 但可能值得查看记录的生成方式 - 理想情况下,您应该尽早在管道中纠正任何问题。
我不知道您的确切情况,但您应该仔细考虑这里的建议- 您可能希望将元数据集中到一个单独的表中,并将其FOREIGN KEY
连接到父记录?
归档时间: |
|
查看次数: |
852 次 |
最近记录: |