簡體   English   中英

如何使用psycopg2將JSON批量加載到Postgres中?

[英]How can I bulk load JSON into Postgres using psycopg2?

我一直在從這樣的文件加載json數據:

with open("data.json") as jd:
    print("loading json")
    j = json.load(jd)
    print("inserting")
    SendToPostGres(j)

def SendToPostGres(incs):
    length = len(incs)
    processed = 0
    pgParams = {
            'database': 'mydb',
            'user': 'hi',
            'password': '2u',
            'host': 'somedb.com',
            'port': 1111
            }
    conn = psycopg2.connect(**pgParams)
    curs = conn.cursor()

    for i in incs:
        curs.execute("insert into MY_TABLE (data) values (%s)", [Json(i)])
        processed += 1
        conn.commit()
        print("%s processed, %s remaining" % (processed, length+1-processed))

這是非常低效的。 我嘗試使用谷歌搜索並查看其他文章,但似乎無法達到預期的效果:“對於json列表中的每個項目,在數據庫中創建一行,並將對應的數據存儲為json類型在postgres中。”

有人可以向我解釋最有效的批量方法嗎?

更新

根據下面的答案,我嘗試過使用附加功能中的execute_values函數。 我現在收到的錯誤是:

“字符串索引超出范圍”

請注意,我嘗試更改頁面大小,因為我認為這可能是相關的。 我試過的沒用。 但這可能仍然是一個問題。

def SendToPostGres(incs):
    values = []
    for i in incs:
        values.append(json.dumps(i))

    pgParams = {
            'database': 'MY_DB',
            'user': 'hi',
            'password': '2u',
            'host': 'somedb.com',
            'port': 5432
            }
    conn = psycopg2.connect(**pgParams)
    curs = conn.cursor()

    try:
        psycopg2.extras.execute_values(curs, "insert into incidents (data) values (%s)", values, page_size=len(values))
    except Exception as e:
        raise e
    rows = curs.fetchall()
    curs.close()

使用psycopg2中的extras.execute_values。

在查詢中使用'%s'語法指定應在何處注入值。

與您當前的方法相比,這非常快。

from psycopg2 import extras

def queryPostgresBulk(conn, query, values):

    _query = query
    _values = values
    _conn = conn
    _cur = _conn.cursor()
    try:
        extras.execute_values(_cur, _query, _values, page_size=_values.__len__())
    except Exception, e:
        raise e
    rows = _cur.fetchall()
    _cur.close()

    return rows

更新到OP評論:

使用json.dumps()將您的字典列表轉換為json字符串的字符串元組列表,該字符串是函數期望的格式。 向其傳遞json字符串json字符串元組列表,而不是表示json對象的字典。

import json

_values = []
for dict in list
    _values.append((json.dumps(dict),))

或具有列表理解功能:

_values = [(json.dumps(x),) for x in list]

還需要指出的是,如果沒有頂級密鑰,則要加載的數據不是有效的json格式。

再次更新為OP評論:

您需要提供一個元組列表作為值,並且json字符串在該元組中。 如果要插入值的唯一數據是json字符串,則需要將for循環構建值更新為:

for i in incs:
    values.append((json.dumps(i),))

不確定我為什么要發布此問題,因為您對問題的兩個早期版本的正確答案不滿意...希望對其他人有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM