我使用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一起使用
答案 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)
完成操作后,别忘了提交更改!