在postgres 9.5中插入包含json对象的数组作为行

Posted

技术标签:

【中文标题】在postgres 9.5中插入包含json对象的数组作为行【英文标题】:Inserting array containing json objects as rows in postgres 9.5 【发布时间】:2016-08-31 13:12:02 【问题描述】:

刚开始使用 PostgreSQL 9.5 并遇到了我的第一个 jsonb 列问题。一段时间以来,我一直试图找到答案,但失败了。有人可以帮忙吗?

我在 python 中有一个 json 数组,其中包含这样的 json 对象:

["name":"foo", "age":"18", "name":"bar", "age":"18"]

我正在尝试将其插入到这样的 jsonb 列中:

COPY person(person_jsonb) FROM '/path/to/my/json/file.json';

但只有 1 行被插入。我希望将数组中的每个 json 对象作为一个新行,如下所示:

1. "name":"foo", "age":"18"
2. "name":"bar", "age":"18"

也试过了:

INSERT INTO person(person_jsonb)
                VALUES (%s)
                ,(json.dumps(data['person'])

仍然只有一行被插入。有人可以帮忙吗?

编辑:按要求添加 python 代码

import psycopg2, sys, json

con = None
orders_file_path = '/path/to/my/json/person.json'

try:

    with open(orders_file_path) as data_file:
        data = json.load(data_file)
    con = psycopg2.connect(...)
    cur = con.cursor()
    person = data['person']
    cur.execute("""
                    INSERT INTO orders(orders_jsonb)
                    VALUES (%s)
                """, (json.dumps(person), ))
    con.commit()

    except psycopg2.DatabaseError, e:
        if con:
            con.rollback()

    finally:

        if con:
           con.close()

person.json 文件:

"person":["name":"foo", "age":"18", "name":"bar", "age":"18"]

【问题讨论】:

显示您正在复制的文件的一些行。显示尝试insert的相关代码。 感谢您的反馈。我进行了一些编辑以包含更多详细信息:) 【参考方案1】:

假设最简单的模式:

CREATE TABLE test(data jsonb);

选项 1:在 Python 中解析 JSON

您需要将PostgreSQL中的每一行分开插入,您可以解析JSON on Python side并拆分上层数组,然后使用cursor.executemany执行INSERT,每个json数据已经拆分:

import json
import psycopg2

con = psycopg2.connect('...')

cur = con.cursor()

data = json.loads('["name":"foo", "age":"18", "name":"bar", "age":"18"]')

with con.cursor() as cur:
    cur.executemany('INSERT INTO test(data) VALUES(%s)', [(json.dumps(d),) for d in data])

con.commit()
con.close()

选项 2:在 PostgreSQL 中解析 JSON

另一种选择是推送JSON processing into PostgreSQL side using json_array_elements

import psycopg2

con = psycopg2.connect('...')

cur = con.cursor()

data = '["name":"foo", "age":"18", "name":"bar", "age":"18"]'

with con.cursor() as cur:
    cur.execute('INSERT INTO test(data) SELECT * FROM json_array_elements(%s)', (data,))

con.commit()
con.close()

【讨论】:

execute_batch (see here) 将提供比 executemany 更好的性能

以上是关于在postgres 9.5中插入包含json对象的数组作为行的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Slick 在 Postgres 中将 json 对象插入到 jsonb 类型的列中

Postgres Plus Advanced Server (PPAS) 9.5 是不是支持将属性更改(删除/添加)复合对象类型?

如何使用pyspark将json对象插入postgres表中的列

如何在 postgres 中使用 Java 插入 json 文档

Postgres 9.5 中使用 regexp_replace 的正向 Lookbehind

PostgreSQL 9.5 - 将 NULL 与 JSON 合并时更新不起作用