Dateien herunterladen und in einem Verzeichnis ablegen
Das hat nichts mit irgendetwas auf dem Server zu tun. Die unkomprimierten Daten passen einfach nicht in den Arbeitsspeicher. Welche Größe haben denn die Daten unkomprimiert? Du darfst eben nicht alles auf einmal lesen, sondern mußt in Blöcken arbeiten.
Eine Datei unkomprimiert ist zwischen 100 und 130 Megabyte groß. Das sind doch gepackte Dateien im gzip Format, welche zwischen 8,5 und 10 Megabyte groß sind. Also mehr RAM und nur einige wenige Daten herunterladen. Pause machen und dann weder starten. Meinst Du das mit in Blöcken arbeiten?
@aaron: Pause machen hilft nicht wenn man den Speicher voll müllt und nach der Pause damit weiter macht. Es sieht so aus als wenn Du mehr als eine dieser Dateien gleichzeitig entpackt im Speicher hältst, das ist/wird dann halt problematisch. 5 Dateien entpackt sind dann 500 bis 650 MiB, plus vielleicht die ungepackten Daten — wir wissen ja nicht was Du da genau machst.
Du darfst halt immer nur eine Datei zu einer Zeit verarbeiten, also herunterladen, entpacken, speichern. Und dann vielleicht auch nicht die entpackten Daten im Speicher halten. Das macht ja sowieso nicht so viel Sinn. Im `shutil`-Modul gibt es Funktionen die dabei behilflich sein können die Daten direkt vom `GzipFile`-Objekt in ein Dateiobjekt zu kopieren, wobei sie ja auch gleich entpackt werden. Und diese Funktionen lesen auch nicht die komplette Quelldatei in den Speicher, sondern kopieren blockweise.
Du darfst halt immer nur eine Datei zu einer Zeit verarbeiten, also herunterladen, entpacken, speichern. Und dann vielleicht auch nicht die entpackten Daten im Speicher halten. Das macht ja sowieso nicht so viel Sinn. Im `shutil`-Modul gibt es Funktionen die dabei behilflich sein können die Daten direkt vom `GzipFile`-Objekt in ein Dateiobjekt zu kopieren, wobei sie ja auch gleich entpackt werden. Und diese Funktionen lesen auch nicht die komplette Quelldatei in den Speicher, sondern kopieren blockweise.
Vielen Dank für den Hinweis auf das `shutil`-Modul.
https://github.com/joergklein/Datawarehouse.git
Ich lerne gerade Handling Exceptions. Entschuldigt bitte meine Fragen. Ich bin Anfänger.
Ich habe ein Gitlab Repo angelegt. Hilfe, Tipps, Tricks und konstruktive Kritik sind sehr willkommen.@aaron: Pause machen hilft nicht wenn man den Speicher voll müllt und nach der Pause damit weiter macht. Es sieht so aus als wenn Du mehr als eine dieser Dateien gleichzeitig entpackt im Speicher hältst, das ist/wird dann halt problematisch. 5 Dateien entpackt sind dann 500 bis 650 MiB, plus vielleicht die ungepackten Daten — wir wissen ja nicht was Du da genau machst.
https://github.com/joergklein/Datawarehouse.git
Ich lerne gerade Handling Exceptions. Entschuldigt bitte meine Fragen. Ich bin Anfänger.
@aaron: Also bei mir läuft das gerade ohne Probleme. Der Traceback verrät ja das es um das Jahr 2015 ging und das Programm ist gerade bei ``data/EURUSD/2015/39.csv.gz``.
Wieviel RAM hast Du denn in dem Rechner?
Wieviel RAM hast Du denn in dem Rechner?
Vielen Dank das Du dir die Zeit nimmst Dir meine Idee anzusehen. Dank der Hilfe von Sirius3. Der Rechner auf dem ich den Test ausgeführt habe hat 64GB RAM und als Betriebssystem verwende ich CentOS 7. Ich werde alle Daten vom 01.01. 1999 (Erster Handel mit dem Euro) bis heute von 40 Währungspaaren archivieren. Das ist eine sehr große Sammlung an Daten, die in einer Datenbank archiviert werden sollen. Das macht circa 5 Terabyte an Datenvolumen.
Also das lief bei mir problemlos durch ohne Speicherprobleme. Kann ich auch nicht nachvollziehen wie das passieren konnte. :K
Danke für das Testen und die gute Nachricht, daß sich die Größe der entpackten Dateien um die Hälfte reduzieren läßt.
Ich bin gerade dabei mich mit dem exception handlung zu beschäftigen. Ich habe folgende Fragen. Sollte ich zu jeder Funktion ein exeption handling schreiben? Ich habe zu Testzwecken ein Symbol gewählt, von dem ich weiß, das dieses nicht auf dem Server vorhanden ist. Der IO Error wird mir angezeigt. Der ValueError nicht, weil die Information von der Funktion main() and die Funktion fetch_single_week übergeben wird. Ist das exception handling für die eine Funktion halbwegs richtig?
Ich bekomme folgende Fehlermeldung:
Ich bin gerade dabei mich mit dem exception handlung zu beschäftigen. Ich habe folgende Fragen. Sollte ich zu jeder Funktion ein exeption handling schreiben? Ich habe zu Testzwecken ein Symbol gewählt, von dem ich weiß, das dieses nicht auf dem Server vorhanden ist. Der IO Error wird mir angezeigt. Der ValueError nicht, weil die Information von der Funktion main() and die Funktion fetch_single_week übergeben wird. Ist das exception handling für die eine Funktion halbwegs richtig?
Ich bekomme folgende Fehlermeldung:
Code: Alles auswählen
python TickDataCsv27.py
Traceback (most recent call last):
File "TickDataCsv27.py", line 90, in <module>
main()
File "TickDataCsv27.py", line 87, in main
fetch_single_week("EURCAD", 2017, 1)
File "TickDataCsv27.py", line 48, in fetch_single_week
except IOError as (errno, strerror):
ValueError: need more than 0 values to unpack
Code: Alles auswählen
def fetch_single_week(symbol, year, week):
try:
if not exists_file(symbol, year, week):
data = pull_file(symbol, year, week)
print_data_length(data)
save_file(symbol, year, week, data)
else:
print("File for {}/{}/{} already fetched.".format(symbol, year, week))
except IOError as (errno, strerror):
print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
print "The requested file does not exist on the server."
except:
print "Unexpected error:", sys.exec_info()[0]
raise
def main():
# "symbol", year, week
fetch_single_week("EURCAD", 2017, 1)
if __name__ == '__main__':
main()
Zuletzt geändert von Anonymous am Donnerstag 23. März 2017, 10:46, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
@aaron: Man sollte nur Ausnahmen behandeln die man tatsächlich sinnvoll behandeln kann.
Das mit dem `ValueError` habe ich nicht verstanden? An welcher Stelle genau erwartest Du den und unter welchen Umständen? Ausnahmebehandlung sollte nicht zu viel Code behandeln, das gilt um so mehr je generischer die Ausnahme ist. `ValueError` kann ja alles mögliche bedeuten, das also die Ausgegebene Meldung stimmt das die Datei nicht auf dem Server existiert, halte ich für ziemlich gewagt. Das kann auch andere Gründe haben.
Tuple unpacking auf Ausnahmen anwenden ist vielleicht keine so gute Idee. So etwas habe ich schon ziemlich lange nicht mehr gesehen — wo hast Du diese Idee denn her? Da muss man etwas über die Anzahl und Reihenfolge der Argumente der `__init__()` von der jeweiligen Ausnahme wissen, und wenn das nicht stimmt, weil sich etwas an der Ausnahme selbst geändert hat oder man einen abgeleiteten Typ mit einer anderen/erweiterten `__init__()`-Signatur bekommt, dann funktioniert das nicht mehr. Und `IOError` verhält sich an der Stelle ja anscheinend noch nicht einmal wie erwartet, also nicht einmal die ”message” ist dort entpackbar.
Der letzte ``except``-Zweig macht sehr wahrscheinlich keinen Sinn.
Das mit dem `ValueError` habe ich nicht verstanden? An welcher Stelle genau erwartest Du den und unter welchen Umständen? Ausnahmebehandlung sollte nicht zu viel Code behandeln, das gilt um so mehr je generischer die Ausnahme ist. `ValueError` kann ja alles mögliche bedeuten, das also die Ausgegebene Meldung stimmt das die Datei nicht auf dem Server existiert, halte ich für ziemlich gewagt. Das kann auch andere Gründe haben.
Tuple unpacking auf Ausnahmen anwenden ist vielleicht keine so gute Idee. So etwas habe ich schon ziemlich lange nicht mehr gesehen — wo hast Du diese Idee denn her? Da muss man etwas über die Anzahl und Reihenfolge der Argumente der `__init__()` von der jeweiligen Ausnahme wissen, und wenn das nicht stimmt, weil sich etwas an der Ausnahme selbst geändert hat oder man einen abgeleiteten Typ mit einer anderen/erweiterten `__init__()`-Signatur bekommt, dann funktioniert das nicht mehr. Und `IOError` verhält sich an der Stelle ja anscheinend noch nicht einmal wie erwartet, also nicht einmal die ”message” ist dort entpackbar.
Der letzte ``except``-Zweig macht sehr wahrscheinlich keinen Sinn.
Ich habe die Idee von hier: http://www.python-kurs.eu/ausnahmebehandlung.php
In der main() Funktion steht folgende Zeile fetch_single_week("EURCAD", 2017, 1). Das Symbol ist zur Zeit wirklich nicht auf dem Server vorhanden. In welcher Funktion baue ich nun den ersten try Block ein? Ich möchte danach ein Logfile erstellen und per Email versenden.
In der main() Funktion steht folgende Zeile fetch_single_week("EURCAD", 2017, 1). Das Symbol ist zur Zeit wirklich nicht auf dem Server vorhanden. In welcher Funktion baue ich nun den ersten try Block ein? Ich möchte danach ein Logfile erstellen und per Email versenden.
@aaron: Das ist mit Vorsicht zu geniessen. An der Stelle steht mitten in dem deutschsprachigen Tutorial englischer Text‽ Nun ja, und es muss halt nicht Stimmen das sich Ausnahmen wie Tupel verhalten, und selbst wenn sie das tun, gibt es die von mir angesprochenen Probleme mit Anzahl und Reihenfolge der Elemente.
Über sinnvolle Fehlerbehandlung steht da auch nicht viel, nur wie das halt syntaktisch aussieht. Und das nackte ``except:`` zur Sicherheit am Ende was eine Ausgabe mit ``print`` macht und dann die Ausnahme wieder auslöst, ist auch eher für die Demonstration der Syntax und nicht etwas was man in jedem Fall an jede Ausnahmebehandlung anhängen sollte.
Bei dem kurzen Abschnitt über ``assert`` irritiert mich das damit etwas ”gefangen” wird, was ja das Gegenteil von ”werfen” ist. Aber genau das macht ``assert``: Ausnahmen ”werfen”. Und mir fehlt auch der deutliche Hinweis, dass der Ausdruck bei ``assert`` keine Effekte haben darf die Einfluss auf das Programm haben, weil nicht garantiert ist, dass ``assert``-Anweisungen überhaupt ausgeführt werden. Es wäre auch die Erklärung nett gewesen das ``assert`` nur Sachen überprüfen sollte von denen der Programmierer an der Stelle ausgeht das die immer wahr sind, weil sonst innerhalb des Programms ein Fehler sein muss, und nicht beispielsweise zum Prüfen von Fehlern in der Benutzereingabe. Der Abschnitt erklärt die Syntax, aber danach denke ich nicht das ein Anfänger weiss was er mit der Anweisung machen sollte und was nicht.
Welche Fehlerbehandlung wo Sinn macht, kommt ganz darauf an wo und wie Du eine Ausnahme behandeln möchtest. Als erstes müsstest Du schauen welche Ausnahme Du behandeln musst. Wenn der Ort wo Du die letztendlich behandeln möchtest weiter entfernt ist von der Stelle wo sie auftritt und die Ausnahme sehr generisch ist, musst Du wahrscheinlich sogar an zwei Stellen ansetzen und selbst eine spezifischere Ausnahme einführen. In diesem Fall vermute ich allerdings einen `urllib2.HTTPError` wenn die Daten nicht auf dem Server existieren. Der ja gleichzeitig ein `IOError` ist, allerdings mit einem leeren `args`-Tupel, was dann genau zu dem Problem führt das Du das nicht auf zwei Namen entpacken kannst. Eine `errno` hat der auch gar nicht, beziehungsweise ist die in diesem Fall `None`. Das Attribut existiert da nur weil es von `IOError` geerbt ist. Den HTTP-Fehlercode bekommt man von der Ausnahme mit der `getcode()`-Methode wenn man bei der Behandlung des Fehlers testen möchte ob es ein 404 war oder etwas anderes.
Für Logfiles würde sich das `logging`-Modul aus der Standardbibliothek anbieten. Logger haben dort auch eine Methode um Ausnahmen zu protokollieren. Zudem kann man das auch so konfigurieren das die Ausgaben an mehreren Stellen landen, also beispielsweise in einer Datei und auf der Standardfehlerausgabe des Prozesses, so dass man sich redundante ``print``-Ausgaben komplett sparen kann.
Über sinnvolle Fehlerbehandlung steht da auch nicht viel, nur wie das halt syntaktisch aussieht. Und das nackte ``except:`` zur Sicherheit am Ende was eine Ausgabe mit ``print`` macht und dann die Ausnahme wieder auslöst, ist auch eher für die Demonstration der Syntax und nicht etwas was man in jedem Fall an jede Ausnahmebehandlung anhängen sollte.
Bei dem kurzen Abschnitt über ``assert`` irritiert mich das damit etwas ”gefangen” wird, was ja das Gegenteil von ”werfen” ist. Aber genau das macht ``assert``: Ausnahmen ”werfen”. Und mir fehlt auch der deutliche Hinweis, dass der Ausdruck bei ``assert`` keine Effekte haben darf die Einfluss auf das Programm haben, weil nicht garantiert ist, dass ``assert``-Anweisungen überhaupt ausgeführt werden. Es wäre auch die Erklärung nett gewesen das ``assert`` nur Sachen überprüfen sollte von denen der Programmierer an der Stelle ausgeht das die immer wahr sind, weil sonst innerhalb des Programms ein Fehler sein muss, und nicht beispielsweise zum Prüfen von Fehlern in der Benutzereingabe. Der Abschnitt erklärt die Syntax, aber danach denke ich nicht das ein Anfänger weiss was er mit der Anweisung machen sollte und was nicht.
Welche Fehlerbehandlung wo Sinn macht, kommt ganz darauf an wo und wie Du eine Ausnahme behandeln möchtest. Als erstes müsstest Du schauen welche Ausnahme Du behandeln musst. Wenn der Ort wo Du die letztendlich behandeln möchtest weiter entfernt ist von der Stelle wo sie auftritt und die Ausnahme sehr generisch ist, musst Du wahrscheinlich sogar an zwei Stellen ansetzen und selbst eine spezifischere Ausnahme einführen. In diesem Fall vermute ich allerdings einen `urllib2.HTTPError` wenn die Daten nicht auf dem Server existieren. Der ja gleichzeitig ein `IOError` ist, allerdings mit einem leeren `args`-Tupel, was dann genau zu dem Problem führt das Du das nicht auf zwei Namen entpacken kannst. Eine `errno` hat der auch gar nicht, beziehungsweise ist die in diesem Fall `None`. Das Attribut existiert da nur weil es von `IOError` geerbt ist. Den HTTP-Fehlercode bekommt man von der Ausnahme mit der `getcode()`-Methode wenn man bei der Behandlung des Fehlers testen möchte ob es ein 404 war oder etwas anderes.
Für Logfiles würde sich das `logging`-Modul aus der Standardbibliothek anbieten. Logger haben dort auch eine Methode um Ausnahmen zu protokollieren. Zudem kann man das auch so konfigurieren das die Ausgaben an mehreren Stellen landen, also beispielsweise in einer Datei und auf der Standardfehlerausgabe des Prozesses, so dass man sich redundante ``print``-Ausgaben komplett sparen kann.
Vielen Dank für die ausführliche Antwort. Ich brauche ein deutschsprachiges Handbuch. Ein Link reicht völlig. Das welches ich hier erwähnt habe scheint nicht wirklich gut zu sein. Aktuell arbeite ich noch mit Python 2.7.x. Das Script wird es später auch in der Python Version 3.5.x geben.
Hier eine Idee für urllib2.HTTPError
Wenn ich dich richtig verstanden habe, dann sollte ich mein Augenmerk auf das `logging`-Modul aus der Standardbibliothek legen? Wer von euch hat so ein ähnliches Problem schon einmal gelöst?Für Logfiles würde sich das `logging`-Modul aus der Standardbibliothek anbieten. Logger haben dort auch eine Methode um Ausnahmen zu protokollieren. Zudem kann man das auch so konfigurieren das die Ausgaben an mehreren Stellen landen, also beispielsweise in einer Datei und auf der Standardfehlerausgabe des Prozesses, so dass man sich redundante ``print``-Ausgaben komplett sparen kann.
Hier eine Idee für urllib2.HTTPError
Code: Alles auswählen
import urllib2
try:
urllib2.urlopen("some url")
except urllib2.HTTPError as err:
if err.code == 404:
print „The requested URL [URL] was not found on this server.“
else:
raise
Zuletzt geändert von Anonymous am Donnerstag 23. März 2017, 13:47, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
@aaron: Wenn man Python 2 und 3 unterstützen möchte sind zwei unabhängige Programme IMHO die letzte Wahl. Ich würde da eher eine Quelltextbasis schreiben die mit beiden Versionen läuft. Da gibt es auch Bibliotheken die dabei helfen, wie `future` oder `six`. Und bei HTTP-Kram das externe `requests` statt der `urllib*`-Module aus der Standardbibliothek.
Zur Ausnahmebehandlung: Ja so würde das ungefähr syntaktisch aussehen und nein das macht natürlich so keinen Sinn, ausser die Aufgabe ist tatsächlich nur: Mache eine Ausgabe wenn keine Ressource für 'some url' gefunden wird.
Statt deutschem Handbuch wäre Englisch lernen wahrscheinlich die bessere Alternative. Denn es wird keine gute und aktuelle deutsche Übersetzung der gesamten Python-Dokumentation geben. Schon gar nicht wenn man Bibliotheken ausserhalb der Standardbibliothek mit hinzu zieht. Auch Domänenwissen, beispielsweise über HTTP steht direkt in der Regel erst einmal in Englisch zur Verfügung. Ob es dafür dann Übersetzungen gibt und wie gut die sind…
Zur Ausnahmebehandlung: Ja so würde das ungefähr syntaktisch aussehen und nein das macht natürlich so keinen Sinn, ausser die Aufgabe ist tatsächlich nur: Mache eine Ausgabe wenn keine Ressource für 'some url' gefunden wird.
Statt deutschem Handbuch wäre Englisch lernen wahrscheinlich die bessere Alternative. Denn es wird keine gute und aktuelle deutsche Übersetzung der gesamten Python-Dokumentation geben. Schon gar nicht wenn man Bibliotheken ausserhalb der Standardbibliothek mit hinzu zieht. Auch Domänenwissen, beispielsweise über HTTP steht direkt in der Regel erst einmal in Englisch zur Verfügung. Ob es dafür dann Übersetzungen gibt und wie gut die sind…
Ich habe jetzt folgendes versucht:
Der 404 Fehler und Not a gzipped file wird angezeigt. Jetzt sollte sich das Programm normal beenden, ohne den Traceback ... Ist die Idee jetzt richtig? Die Ausgabe sieht jetzt so aus:
Code: Alles auswählen
def pull_file(symbol, year, week):
try:
url = URL_TEMPLATE.format(symbol, year, week)
response = urllib2.urlopen(url)
return response.read()
except urllib2.HTTPError, e:
print e.code
except urllib2.URLError, e:
print e.args
Code: Alles auswählen
404
Traceback (most recent call last):
File "TickDataCsv27.py", line 85, in <module>
main()
File "TickDataCsv27.py", line 82, in main
fetch_single_week("EURCAD", 2017, 1)
File "TickDataCsv27.py", line 46, in fetch_single_week
print_data_length(data)
File "TickDataCsv27.py", line 32, in print_data_length
data = f.read()
File "/usr/lib64/python2.7/gzip.py", line 254, in read
self._read(readsize)
File "/usr/lib64/python2.7/gzip.py", line 296, in _read
self._read_gzip_header()
File "/usr/lib64/python2.7/gzip.py", line 190, in _read_gzip_header
raise IOError, 'Not a gzipped file'
IOError: Not a gzipped file
Zuletzt geändert von Anonymous am Donnerstag 23. März 2017, 15:15, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
@aaron: das ist nicht richtig, weil Du ja im Fehlerfall nichts sinnvolles machst. An der Stelle muß also eine Fehlerbehandlung eine andere Exception werfen, die dann weiter oben verarbeitet werden kann, oder gleich ganz entfallen.
Gut ich werde jetzt das exepition handling in den Griff bekommen und dann die die Quelltextbasis für Python 2 und 3 erstellen.BlackJack hat geschrieben:@aaron: Wenn man Python 2 und 3 unterstützen möchte sind zwei unabhängige Programme IMHO die letzte Wahl. Ich würde da eher eine Quelltextbasis schreiben die mit beiden Versionen läuft. Da gibt es auch Bibliotheken die dabei helfen, wie `future` oder `six`. Und bei HTTP-Kram das externe `requests` statt der `urllib*`-Module aus der Standardbibliothek.
Meine Englischkenntnisse sind relativ gut. Es ist diese Bequemlichkeit, die sich gern bei mir einschleicht. Ein deutschsprachiges Buch läßt sich für mich leichter lesen als ein englischsprachiges Buch.Zur Ausnahmebehandlung: Ja so würde das ungefähr syntaktisch aussehen und nein das macht natürlich so keinen Sinn, ausser die Aufgabe ist tatsächlich nur: Mache eine Ausgabe wenn keine Ressource für 'some url' gefunden wird.
Statt deutschem Handbuch wäre Englisch lernen wahrscheinlich die bessere Alternative. Denn es wird keine gute und aktuelle deutsche Übersetzung der gesamten Python-Dokumentation geben. Schon gar nicht wenn man Bibliotheken ausserhalb der Standardbibliothek mit hinzu zieht. Auch Domänenwissen, beispielsweise über HTTP steht direkt in der Regel erst einmal in Englisch zur Verfügung. Ob es dafür dann Übersetzungen gibt und wie gut die sind…
Bei guten Englischkenntnissen ist dies reine Übungssache. Stürz Dich daher am besten direkt in die englischsprachigen Dokumentationen. Der Markt für deutschsprachige Dokumentationen ist zu klein, um für Autoren wirklich attraktiv zu sein. Und daran wird sich vermutlich auch nichts ändern.aaron hat geschrieben:Meine Englischkenntnisse sind relativ gut. Es ist diese Bequemlichkeit, die sich gern bei mir einschleicht. Ein deutschsprachiges Buch läßt sich für mich leichter lesen als ein englischsprachiges Buch.