在不使用循环的情况下将大量JSON数据插入数据库的其他方法

时间:2019-06-24 13:16:57

标签: python json postgresql

我使用request调用API以获取JSON数据并将其存储在这样的一个变量中:

r = requests.post(url=endpoint , data=payload, headers=headers, params=parameter)
all = json.loads(r.text)

然后我使用循环逐行插入数据,如下所示:

for row in all:
   sql = "INSERT INTO t VALUES ({},{},{});".format(all['id'],all['num'],all['type'])
   cur.execute(sql)

真实的列有更多的列,而不仅仅是示例中的3列。

这段代码可以很好地工作,但是我的问题是,还有其他方法可以将JSON数据插入表中吗?因为我需要为每1个请求插入4-5千行,这将花费很长时间(与CSV文件上的copy_expert相比),因为它逐行插入。有没有不使用循环的方法或任何可能有助于此插入过程更快的方法?

我在这里将PosgreSQL数据库与Python一起使用

2 个答案:

答案 0 :(得分:1)

该技术应该是最快的,因为它不涉及任何客户端循环或解析,但是它要求您json结构中的键与您的列名匹配。

import sys

sys.path.append('/path/to/.sofile')

import region

这是一个例子:

INSERT INTO t 
SELECT * from json_populate_recordset(null::t, your_json);

请注意,最后一行全为空,因为它只包含“ d”,而不是t中的列。

在python中,这将转换为以下内容:

create table t (a int, b int, c int);
insert into t 
select * from json_populate_recordset(null::t, 
             '[{"a": 1, "b": 2}, {"c": 3, "a": 1}, {"b": 4, "a": 7, "c": 9}, {"d": 5}]'
);
select * from t;
 a | b | c
---+---+---
 1 | 2 |
 1 |   | 3
 7 | 4 | 9
   |   |
(4 rows)

答案 1 :(得分:0)

您会发现DBAPI游标不仅具有execute方法,而且还具有为您的目的而设计的execute_many

使用SQL语句作为第一个参数以及一系列元组或列表来调用它,每个元组或列表注定要成为数据库中的一行。

请注意,您现有的代码结构非常危险,因为它很容易受到通过提供JSON的远程站点引导的SQL注入攻击的攻击。还请注意,requests.Response对象具有一种.json方法,可以避免转换的麻烦。由于您没有引用表描述,所以我不知道列名,但是也请意识到,当您提供显式列名时,SQL INSERT语句更加健壮。通过重组表以使列以不同的顺序,现有的代码可能会失效。

将所有这些知识放在一起将为您提供类似以下(未经测试)的代码。

r = requests.post(url=endpoint , data=payload, headers=headers, params=parameter)

data = [(row['id'], row['num'],row['type']) for row in r.json()]
cur.execute_many("INSERT INTO t VALUES ({},{},{})", data)

完成操作后,别忘了提交更改!