【问题标题】:Insert JSON data from REST API into PostgreSQL table using Python使用 Python 将来自 REST API 的 JSON 数据插入 PostgreSQL 表
【发布时间】:2021-04-28 16:18:34
【问题描述】:

我尝试将 json api 的每个元素插入到我的 postgres 表中。

但我得到以下错误:

Traceback (most recent call last):
  File "c:/Users/myname/Documents/repos/docker-playground/parse_json_to_postgres.py", line 20, in <module>
    cursor.execute(f"INSERT into catfacts(data) VALUES (  {cat_fact}  )")
psycopg2.errors.SyntaxError: syntax error at or near "{"
LINE 1: INSERT into catfacts(data) VALUES (  {'status': {'verified':...
                                             ^

我的 postgres 表:

CREATE TABLE cat_facts (
    id serial NOT NULL PRIMARY KEY,
    data jsonb NOT NULL
);

我的 Python 代码将数据插入到表中:

import requests, json, psycopg2  


cat_facts_json = requests.get('https://cat-fact.herokuapp.com/facts').json


conn = psycopg2.connect(user="postgres",
                                password="password",
                                host="localhost",
                                port="5432",
                                database="postgres")

cursor = conn.cursor()

for cat_fact in cat_facts_json():
    cursor.execute(f"INSERT into catfacts(data) VALUES ( \' {cat_fact} \' )")

API = https://cat-fact.herokuapp.com/facts

我想要达到的目标:

INSERT INTO cat_facts(data) VALUES ('{"status":{"verified":true,"sentCount":1},"type":"cat","deleted":false,"_id":"58e008800aac31001185ed07","user":"58e007480aac31001185ecef","text":"Wikipedia has a recording of a cat meowing, because why not?","__v":0,"source":"user","updatedAt":"2020-08-23T20:20:01.611Z","createdAt":"2018-03-06T21:20:03.505Z","used":false}');
INSERT INTO cat_facts(data) VALUES ('{"status":{"verified":true,"sentCount":1},"type":"cat","deleted":false,"_id":"58e008630aac31001185ed01","user":"58e007480aac31001185ecef","text":"When cats grimace, they are usually \"taste-scenting.\" They have an extra organ that, with some breathing control, allows the cats to taste-sense the air.","__v":0,"source":"user","updatedAt":"2020-08-23T20:20:01.611Z","createdAt":"2018-02-07T21:20:02.903Z","used":false},{"status":{"verified":true,"sentCount":1},"type":"cat","deleted":false,"_id":"58e00a090aac31001185ed16","user":"58e007480aac31001185ecef","text":"Cats make more than 100 different sounds whereas dogs make around 10.","__v":0,"source":"user","updatedAt":"2020-08-23T20:20:01.611Z","createdAt":"2018-02-11T21:20:03.745Z","used":false}');

....

【问题讨论】:

  • 你看过这里的答案了吗? psycopg2 insert python dictionary as json
  • 除了@StefanoFrazzetto 的帖子,请参阅Query parameters 了解为什么不应该使用格式化字符串。
  • @AdrianKlaver 我喜欢文档部分,它说:“永远,永远,永远不要使用 Python 字符串连接 (+) 或字符串参数插值 (%) 将变量传递给 SQL 查询字符串。甚至没有在枪口下。”
  • 是的,我在 cat_facts_json() 中为 cat_fact 尝试过: cursor.execute("INSERT into catfacts(data) VALUES ( %s )" % json.dumps(cat_fact) ) 仍然无效同样的错误。
  • 这对于 cat_facts_json() 中的 cat_fact: sql = "INSERT into catfacts(data) VALUES ( %s )" cursor.execute(sql,cat_fact) retuns:Traceback (最近一次调用最后一次):文件“c:/Users/user/Documents/repos/docker-playground/parse_json_to_postgres.py”,第 33 行,在 cursor.execute(sql,cat_fact) TypeError: dict is not a sequence

标签: python json postgresql rest


【解决方案1】:

我现在开始工作了:

for cat_fact in cat_facts_json:

    data = json.dumps(cat_fact)
    insert_query = "insert into cat_facts (data) values (%s) returning data"
    cursor.execute(insert_query, (data,))
    conn.commit()
    conn.close()

我考虑过你的 cmets @Stefano Frazzetto 和 @Adrian Klaver。

  • json.dumps 有效!
  • 我没有直接在执行查询中执行参数

我仍然认为,这是一种在数据后加逗号的非常奇怪的语法:

cursor.execute(insert_query, (data,))

【讨论】:

  • 这是一个漫长的过程:insert_query = "insert into cat_facts (data) values (%s) returning data" cursor.execute(insert_query, (Json(cat_fact),))(data,) 是一个元组,Python 语法要求它有一个逗号以将其与括号中的值区分开来:t = (1,) t[0] 1, t = (1) t[0] 'int' object is not subscriptable。如果您不想这样做,请使用列表。
【解决方案2】:

请看这里JSON Adaption

比如:

from psycopg2.extras import Json

cursor.execute("INSERT into catfacts(data) VALUES (%s)", [Json(cat_fact)])

【讨论】:

  • 还没有,但更接近了。打印工作并返回每个 cat 事实对象。插入不知何故不起作用。对于 cat_facts_json 中的 cat_fact: print(cat_fact) cursor.execute("INSERT into cat_facts(data) VALUES (%s)", [Json(cat_fact)]) 并且在我的 get 查询中错过了 (),现在是 requests.get(' cat-fact.herokuapp.com/facts').json() 而不是 requests.get('cat-fact.herokuapp.com/facts').json。谢谢 Adrian
  • 请将此添加到您可以正确格式化的问题中。当您这样做时,还包括print(cat_fact) 的结果。还要定义“不工作”。
  • 我的回答假设 cat_fact 是一个 Python 对象,就像你从 json.loads(json_str) 得到的一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-23
  • 2016-10-09
  • 1970-01-01
  • 1970-01-01
  • 2021-07-19
  • 2021-10-16
  • 1970-01-01
相关资源
最近更新 更多