Segmentação de valores específicos de JSON API e inserindo em Postgresql, usando Python

votos
1

Agora eu sou capaz de se conectar à api url e meu banco de dados. Eu estou tentando inserir dados do URL para o banco de dados PostgreSQL usando psycopg2. Eu não compreendo perfeitamente como fazer isso, e isso é tudo que eu poderia chegar a fazer isso.

import urllib3
import json
import certifi
import psycopg2
from psycopg2.extras import Json


http = urllib3.PoolManager(
    cert_reqs='CERT_REQUIRED',
    ca_certs=certifi.where())
url = '<API-URL>'
headers = urllib3.util.make_headers(basic_auth='<user>:<passowrd>')
r = http.request('GET', url, headers=headers)
data = json.loads(r.data.decode('utf-8'))


def insert_into_table(data):

    for item in data['issues']:
        item['id'] = Json(item['id'])

    with psycopg2.connect(database='test3', user='<username>', password='<password>', host='localhost') as conn:
        with conn.cursor() as cursor:
            query = 
                INSERT into
                     Countries
                    (revenue)
                VALUES
                    (%(id)s);
            
            cursor.executemany(query, data)

        conn.commit()


insert_into_table(data)

Então este código dê-me um TypeError: string indices must be integersem cursor.executemany(query, data)

Então eu sei que json.loads traz de volta um objeto do tipo e que json.dumps traz um tipo string. Eu não tinha certeza que eu deveria estar usando. e eu sei que eu estou faltando algo completamente sobre como im visando o valor 'id', e inseri-lo na consulta.

Também um pouco sobre a API, é muito grande e complexo e, eventualmente, eu vou ter que ir para baixo várias árvores para pegar certos valores, aqui está um exemplo do que eu estou puxando a partir.

Eu estou tentando agarrar id em questões e não tipo de problema

{
  expand: <>,
  startAt: 0,
  maxResults: 50,
  total: 13372,
  issues: [
    {
      expand: <>,
      id: 41508,
      self: <>,
      key: <>,
      fields: {
        issuetype: {
          self: <>,
          id: 1,
          description: <>,
          iconUrl: <>,
          name: <>,
          subtask: <>,
          avatarId: <>
        },
Publicado 27/11/2018 em 18:00
fonte usuário
Em outras línguas...                            


3 respostas

votos
1

Primeiro, extraia idsem uma lista de tuplas:

ids = list((item['id'],) for item in data['issues'])
# example ids: [('41508',), ('41509',)]

Em seguida, use a função extras.execute_values ():

from psycopg2 import extras

query = """
    INSERT into Countries (revenue)
    VALUES %s;
"""
extras.execute_values(cursor, query, ids)

Por que eu estava recebendo erros de tipo?

O segundo argumento da função executemany (consulta, vars_list) deve ser uma sequência, enquanto dataé um objecto que os elementos não podem ser acedidos por índices de números inteiros.

Por que usar execute_values()em vez de executemany()?

Por causa do desempenho, a primeira função executa uma única consulta com vários argumentos, enquanto o segundo executa como muitas consultas como argumentos.

Note que por padrão, o terceiro argumento execute_values()é uma lista de tuplas, por isso extraído idsapenas desta forma.

Se você tiver que inserir valores em mais de uma coluna, cada tupla na lista deve conter todos os valores para uma única linha inserida, por exemplo:

values = list((item['id'], item['key']) for item in data['issues'])

query = """
    INSERT into Countries (id, revenue)
    VALUES %s;
"""
extras.execute_values(cur, query, values)
Respondeu 27/11/2018 em 19:36
fonte usuário

votos
1

O problema que você tem não é da maneira que você estiver analisando o JSON, ele ocorre quando você tenta inseri-lo em sua mesa usando cursor.executemany().

dataé um único objeto, Você está tentando inserir todos os dados de sua buscar retornos em sua mesa de uma só vez? Ou você está tentando inserir uma parte específica dos dados ( uma lista de edição IDs )?

Você está passando dataem sua cursor.executemanychamada. dataÉ um objecto. Eu acredito que você deseja passar data.issueso que é a lista de questões que você modificou.

Se você só deseja inserir os ids na tabela tente o seguinte:

def insert_into_table(data):

    with psycopg2.connect(database='test3', user='<username>', password='<password>', host='localhost') as conn:
        with conn.cursor() as cursor:
            query = """
            INSERT into
                 Countries
                (revenue)
            VALUES
                (%(id)s);
            """
            for item in data['issues']:
               item['id'] = Json(item['id'])
               cursor.execute(query, item['id')

            conn.commit()


insert_into_table(data)

Se você deseja manter a eficiência do uso cursor.executemany()Você precisa criar uma matriz dos IDs, como a estrutura do objeto atual não organizá-los da forma como o cursor.executemany()exige.

Respondeu 27/11/2018 em 19:29
fonte usuário

votos
1

Se você está tentando obter apenas o ID e inseri-lo em sua mesa, você deve tentar

ids = []
for i in data['issues']:
     ids.append(i['id'])

Então você pode passar o seu idslista para você cursor.executemanyfuncionar.

Respondeu 27/11/2018 em 19:12
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more