Как преобразовать JSON данные в формат Avro с помощью Python - PullRequest
0 голосов
/ 06 августа 2020

Я хотел бы преобразовать приведенные ниже данные JSON в формат avro. Я использовал приведенный ниже фрагмент кода для записи данных JSON в формате avro, но получил ошибку. Если кто-нибудь может с этим помочь, было бы здорово.

from fastavro import writer, reader, schema
from rec_avro import to_rec_avro_destructive, from_rec_avro_destructive, rec_avro_schema

def getweatherdata():
    url = 'https://api.openweathermap.org/data/2.5/onecall?lat=33.441792&lon=-94.037689&exclude=hourly,daily&appid=' + apikey
    response = requests.get(url)
    data = response.text
    return data
 
def turntoavro():
    avro_objects = (to_rec_avro_destructive(rec) for rec in getweatherdata())
    with open('json_in_avro.avro', 'wb') as f_out:
        writer(f_out, schema.parse_schema(rec_avro_schema()), avro_objects)



turntoavro()

    Error details:
    
      File "fastavro/_write.pyx", line 269, in fastavro._write.write_record
    TypeError: Expected dict, got str
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "datalake.py", line 30, in <module>
        turntoavro()
      File "datalake.py", line 26, in turntoavro
        writer(f_out, schema.parse_schema(rec_avro_schema()), avro_objects)
      File "fastavro/_write.pyx", line 652, in fastavro._write.writer
      File "fastavro/_write.pyx", line 605, in fastavro._write.Writer.write
      File "fastavro/_write.pyx", line 341, in fastavro._write.write_data
      File "fastavro/_write.pyx", line 278, in fastavro._write.write_record
    AttributeError: 'str' object has no attribute 'get'

Примеры данных:

    {
      "lat": 33.44,
      "lon": -94.04,
      "timezone": "America/Chicago",
      "timezone_offset": -18000

   }

Ответы [ 2 ]

0 голосов
/ 10 августа 2020

Как упоминалось в одном из ответов, вы, вероятно, захотите использовать response.json(), а не response.text, чтобы получить фактический JSON словарь.

Однако другая проблема заключается в том, что getweatherdata() возвращает единственный словарь, поэтому, когда вы выполняете avro_objects = (to_rec_avro_destructive(rec) for rec in getweatherdata()), вы перебираете ключи в этом словаре. Вместо этого вы должны сделать avro_objects = [to_rec_avro_destructive(getweatherdata())]

Я считаю, что этот код должен работать для вас:

from fastavro import writer, reader, schema
from rec_avro import to_rec_avro_destructive, from_rec_avro_destructive, rec_avro_schema

def getweatherdata():
    url = 'https://api.openweathermap.org/data/2.5/onecall?lat=33.441792&lon=-94.037689&exclude=hourly,daily&appid=' + apikey
    response = requests.get(url)
    data = response.json()
    return data
 
def turntoavro():
    avro_objects = [to_rec_avro_destructive(getweatherdata())]
    with open('json_in_avro.avro', 'wb') as f_out:
        writer(f_out, schema.parse_schema(rec_avro_schema()), avro_objects)

turntoavro()
0 голосов
/ 08 августа 2020

Чтобы получить ответ на сделанный вами запрос, вы использовали response.text, который возвращает ответ в виде строки, а не в формате JSON. Вы должны использовать response.json() вместо этого, чтобы иметь его в формате JSON:

import json    
def getweatherdata():
    url = 'https://api.openweathermap.org/data/2.5/onecall?lat=33.441792&lon=-94.037689&exclude=hourly,daily&appid=' + apikey
    response = requests.get(url)
    data = response.json()
    return data
     
def turntoavro():
    avro_objects = (to_rec_avro_destructive(rec) for rec in getweatherdata())
    with open('json_in_avro.avro', 'wb') as f_out:
        writer(f_out, schema.parse_schema(rec_avro_schema()), avro_objects)
    
    
    
turntoavro()
...