2017-05-07 2 views
1

Als Übung ziehe ich Daten aus einer API und Einfügen in eine PSQL-Datenbank. Ich folgte zunächst dem Standard-Limit von 1000 Einträgen pro Pull, entschied aber, dass ich versuchen wollte, alle Daten zu bekommen, die ungefähr 40K Reihen sind. Nach ein wenig Experimentieren, kann ich 4800, ziehen aber dann bekomme ich folgendes:Python KeyError: <pissewee.IntegerField object at ...> mit peewee insert_many()

Traceback (most recent call last): 
    File "data_pull.py", line 19, in <module> 
    postgres_db.Bike_Count.insert_many(data).execute() 
    File "/usr/local/lib/python3.5/dist-packages/peewee.py", line 3516, in execute 
    cursor = self._execute() 
    File "/usr/local/lib/python3.5/dist-packages/peewee.py", line 2901, in _execute 
    sql, params = self.sql() 
    File "/usr/local/lib/python3.5/dist-packages/peewee.py", line 3484, in sql 
    return self.compiler().generate_insert(self) 
    File "/usr/local/lib/python3.5/dist-packages/peewee.py", line 2084, in generate_insert 
    value = row_dict[field] 
KeyError: <peewee.IntegerField object at 0x7f5b32c2c7f0> 

data_pull.py

import json, requests, peewee 
import postgres_db 


endpoint = 'https://data.seattle.gov/resource/4xy5-26gy.json?$limit=4800' 

response = requests.get(endpoint, headers={'X-App-Token': '(REMOVED)'}) 
if response.status_code == 200: 
    data = json.loads(response.text) 


postgres_db.Bike_Count.create_table(True) 
postgres_db.Bike_Count.insert_many(data).execute() 

postgres_db.py

import peewee 


psql_db = peewee.PostgresqlDatabase('database', user='my_username') 

class Bike_Count(peewee.Model): 
    date = peewee.DateTimeField() 
    fremont_bridge_sb = peewee.IntegerField() 
    fremont_bridge_nb = peewee.IntegerField() 

    class Meta: 
     database = psql_db 

ich angeschaut habe Die Tische online denken, es gab ein Problem mit einem Eintrag dort, aber ich kann nichts Offensichtliches finden. Danke für die Hilfe.

+0

Wie fügen Sie die Antwortdatenfolge direkt in die Tabelle ein, ohne sie je nach Bedarf zu formatieren? Ist die Antwort garantiert eine Liste mit einem Datetime-Wert und zwei Ganzzahlen zurückgeben? – wave5459

+0

Was meinen Sie, indem Sie es notwendigerweise formatieren? Ich verstehe, dass json.loads() ein Objekt zurückgibt, das in diesem Fall eine Liste von Wörterbüchern ist. Die API-Dokumentation sagt, dass die Felder ein Datums-/Uhrzeitfeld und zwei Zahlenfelder sind. Es ist einfach komisch, dass ich einen Tisch mit bis zu 4800 Zeilen bekomme und dann einen Fehler findet. –

+0

Hier ist der Link zu Informationen über den Datensatz: https: //data.seattle.gov/Transportation/Fremont-Bridge-Hourly-Fahrrad-Counts-by-Month-Octo/65db-xm6k –

Antwort

1

ich Ihren Code lokal versucht (Entfernen der App-Token und die 4800 Grenze) und es funktionierte wie erwartet:

id |  date   | fremont_bridge_sb | fremont_bridge_nb 
------+---------------------+-------------------+------------------- 
    1 | 2017-01-09 06:00:00 |    28 |    55 
    2 | 2017-01-04 20:00:00 |    19 |    10 
    3 | 2017-01-18 13:00:00 |    18 |    18 
    4 | 2017-01-06 11:00:00 |    22 |    15 
    5 | 2017-01-27 11:00:00 |    39 |    38 
    6 | 2017-01-08 14:00:00 |     6 |    10 
    7 | 2017-01-06 23:00:00 |     8 |     3 
    8 | 2017-01-27 13:00:00 |    45 |    35 
... 

Was mir auffiel, als ich es mit dem LIMIT lief ist angebracht, dass eine der Zeilen zurückgegeben durch die API enthält nur einen date Schlüssel (fehlt die fremont_bridge_nb und fremont_bridge_sb Felder).

Peewee erfordert für Masseneinfügungen, dass jede Zeile die gleichen Schlüssel hat, so ist das Problem, dass peewee erwartet, alle 3 Schlüssel zu finden.

+0

Vielen Dank für die Fischerei durch die Daten wie das. Das habe ich gestern auch bemerkt; In der Tat gibt es mindestens zwei Zeilen, denen Werte fehlen. Ich habe versucht, '' 'null = True'' zu setzen, um zu sagen, dass es in Ordnung ist, wenn sie null sind, aber nach einiger Fehlersuche habe ich mich schließlich darauf festgelegt, ihre Standardwerte auf 1 zu setzen. –

Verwandte Themen