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

时间:2016-08-31 13:12:02

标签: postgresql psycopg2 jsonb

刚开始使用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';

但只插入了一行。我希望将数组中的每个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"}]}

1 个答案:

答案 0 :(得分:4)

假设最简单的架构:

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