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

Inserting array containing json objects as rows in postgres 9.5

刚开始使用 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"}]}

假设最简单的模式:

CREATE TABLE test(data jsonb);

选项 1:解析 Python

中的 JSON

您需要将 PostgreSQL 中的每一行分开插入,您可以解析 JSON on Python side and split the upper level array, then use cursor.executemany 以对每个 json 已拆分的数据执行 INSERT:

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()