【问题标题】:Inserting array containing json objects as rows in postgres 9.5在postgres 9.5中插入包含json对象的数组作为行
【发布时间】: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的相关代码。
  • 感谢您的反馈。我进行了一些编辑以包含更多详细信息:)

标签: postgresql psycopg2 jsonb


【解决方案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 更好的性能
猜你喜欢
  • 2015-07-02
  • 1970-01-01
  • 1970-01-01
  • 2016-03-13
  • 2014-12-16
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
  • 1970-01-01
相关资源
最近更新 更多