cPickle mit email.message_from_string

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
DnlMrx
User
Beiträge: 4
Registriert: Montag 29. November 2010, 12:29

Hallo zusammen,

in meinem aktuellen Projekt habe ich gerade folgende Situation:

1. Ein Skript holt aktuelle Emails von einem Pop3 Server (diese werden mit mail.retr()) abeholt und danach via email.message_from_string(data) also Emailobjekt mit cPickle.dumps() in eine MYSQL DB abgespeichert, als Blob.

2. Danach will ich mir die Emails nach und nach aus der DB holen und parsen. Die Emails haben keinen konkreten Header und können nicht direkt mit den üblichen Emailparsern behandelt werden.
Mit cpickle.loads() will ich die Daten zur weiteren Verarbeitung wieder in den eigentlichen Zustand zurückbekommen.

Ich bekomme aber leider nur folgendes zurück:

Code: Alles auswählen

From nobody Mon Jan  7 18:15:40 2013
['Return-Path: <vxxx@yyy.de>', 'X-Original-To:
 service@yyy.de', 'Delivered-To: usw


Eine type auf das Objekt bringt nur instance zurück. Mein Ziel ist es die Email als Liste (danach kann ich über alle Elemente iterieren und zusammenfügen) oder als Email Objekt vor mir haben.

Wenn ich mir das message = email.message_from_string(data) spare, klappt es wunderbar.
Das ist leider keine Option mehr, da ich sonst knapp 250k Emails nicht parsen kann.

Ich bin für jeden Vorschlag und Idee sehr dankbar,

Daniel
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Wenn du email.message_from_string(s) aufrufst, dann wird der String geparst und daraus ein Objekt von email.message.Message gebaut. Und wenn du dieses Objekt mit pickle serealisierst und anschließend wieder lädst, dann ist das noch immer ein solches Objekt. Bräuchtest du den originalen String, hättest du eben diesen speichern müssen.
Allerdings sollten durch das Parsen eigentlich keine relevanten Daten verloren gehen.
BlackJack

@DnlMrx: So grundsätzlich kann ich das Problem nicht nachvollziehen. Ich kann mit `cPickle` problemlos `email.message.Message`-Objekte serialisieren und auch wieder deserialisieren.

Verwendest Du für beide Vorgänge die gleiche Python-Version? Welche Version(en)? Hast Du es mal ohne die Datenbank dazwischen ausprobiert? Sind die Daten, die Du in die DB herein steckst mit denen identisch, die das andere Skript wieder heraus holt?

Pickle ist kein Format das ich für längerfristige Persistenz von wichtigen Daten empfehlen würde, solange man sich nicht ziemlich sicher ist, dass sich an der Paket und Objektstruktur im Programm, oder in diesem Fall in der Standardbibliothek, nichts ändern wird. Denn es werden nur die Nutzdaten gespeichert und nicht die Klassen. Wenn man Klassen verschiebt oder sich die Attribute verändern, dann passen schnell die gespeicherten Daten nicht mehr dazu. Das heisst man sollte sich auf wenige grundlegende Datentypen beschränken, die sich mit an Sicherheit grenzender Wahrscheinlichkeit nicht ändern werden. Also zum Beispiel Listen, Tupel, Mengen, Wörterbücher, Zahlen, Zeichenketten und so weiter. Nichts so komplexes wie E-Mail-Objekte. Und wenn man sich auf die grundlegenden Typen beschränkt, kann man meistens auch JSON verwenden. Was den Vorteil hat, nicht an Python gebunden zu sein.

Pickles sind damit nicht wertlos, denn sie eignen sich immer noch ganz gut um komplexere Objektstrukturen zu cachen wenn das deserialisieren schneller geht als das neu erstellen.
Antworten