Seite 1 von 1
MySQLdb und BLOB >64KB Grenze???
Verfasst: Donnerstag 2. November 2006, 21:47
von jens
Ich hab gerade ein neues Plugin für PyLucid geschrieben: FileStore
Dabei werden Dateien per BLOB in der MySQL DB gespeichert. Dabei gibt es zwei Probleme:
1. Ich erhalte die Daten in Form von einem array-Objekt zurück
2. Es gibt irgendwie eine max. Grenze von 64KB
Zu 1. hab ich eine einfache Lösung: result = result.tostring() und fertig.
Zu 2. hab ich keinen Plan
Jemand eine Idee?
Verfasst: Freitag 3. November 2006, 00:44
von BlackJack
Im allgemeinen haben so grosse Daten nichts in DBs zu suchen. Normalerweise speichert man dort einen Pfad ab wo die Datei im Dateisystem zu finden ist.
Gibt's bei MySQL nicht den Typ `longblob` für max. 4 GB grosse blobs?
Verfasst: Freitag 3. November 2006, 11:09
von jens
Ja, ich weiß. Für den Einsatzzweck ist das allerdings IMHO OK
LONGBLOB ist es wohl

Dank dir!
Verfasst: Freitag 3. November 2006, 12:10
von jens
So, hab nun LONGBLOB genommen... Nun geht's bis ca. 870KB, bei größeren Uploads kommt ein Traceback mit "MySQL server has gone away"
Ist ärgerlich, aber ok, um seine Bookmarks zu tauschen (ist bei mit 750KB groß)
Ich könnte ja noch die Daten on-thy-fly mit ZIP komprimieren

Verfasst: Freitag 3. November 2006, 14:56
von Leonidas
jens hat geschrieben:Ist ärgerlich, aber ok, um seine Bookmarks zu tauschen (ist bei mit 750KB groß)
Für sowas gibt es
Gavril, du kannst mal gucken, ob es mit so großen Dateien umgehen kann.
Verfasst: Freitag 3. November 2006, 15:01
von jens
Leonidas hat geschrieben:Für sowas gibt es
Gavril, du kannst mal gucken, ob es mit so großen Dateien umgehen kann.
Und wie speicherst du da die Dateien? Lokal in's Dateisystem?
Auf
http://django.benitum.de/gavril/ gibt echt wenig Info's. Wo ist der Sourcecode/Download ?
Verfasst: Freitag 3. November 2006, 15:13
von Leonidas
jens hat geschrieben:Und wie speicherst du da die Dateien? Lokal in's Dateisystem?
Nö, in eine PostgreSQL-Datenbank. Ich dir nicht mit 100%iger Sicherheit sagen, wo die Obergrenze ist, müsste die Doku mal wälzen.
Welche Informationen fehlen dir denn? Dort was dazuzuschreiben ist kein Problem.
jens hat geschrieben:Wo ist der Sourcecode/Download ?
Der Quelltext ist nur auf Anfrage verfügbar. Warum? 1) Weil ich dort "live" entwickle und es daher keine "Milestones" gibt, die man in einen Tarball packen könnte 2) weil der COde sehr d.b.d-zentrisch ist und vermutlich schwer für andere Umgebungen anpassbar.
Verfasst: Freitag 3. November 2006, 15:15
von jens
Nutz doch zumindest SVN oder was ähnliches... Wo man nachschauen kann...
Aber gut, da es PostgreSQL nutzt ist es eh nix für mich

Verfasst: Freitag 3. November 2006, 15:34
von Leonidas
jens hat geschrieben:Nutz doch zumindest SVN oder was ähnliches... Wo man nachschauen kann...
Wäre eine Möglichkeit, aber die Projekte haben keine ausreichende "Schaffenshöhe" dass ich dafür ein SCM-Repository aufsetzen müsste.
jens hat geschrieben:Aber gut, da es PostgreSQL nutzt ist es eh nix für mich

- Du kannst für deine Bookmarks d.b.d verwenden, dafür ist es eben da
- Gavril ist nicht an eine bestimmte Datenbank gebunden. Es funktioniert mit PostgreSQL, MySQL, SQLite usw. Ich nutze eben PostgreSQL.
Verfasst: Freitag 3. November 2006, 16:38
von jens
Ach Schnickschnack! Ein SVN und ein Verz. "CodeSnippes" und fertig... Muß ja nicht ein SVN pro Projekt sein

Du hast ja schon so einiges hier und da gemacht...
Zu 1. Achso... Du meinst ist nutzte deinen Dienst, so wie ein öffentlicher Paste Dienst... Ich dachte immer es wäre nur eine Art Demo...
Zu 2. Wie ist die DB Anbindung gelöst?
Verfasst: Freitag 3. November 2006, 17:47
von Leonidas
jens hat geschrieben:Ach Schnickschnack! Ein SVN und ein Verz. "CodeSnippes" und fertig... Muß ja nicht ein SVN pro Projekt sein

Du hast ja schon so einiges hier und da gemacht...
Ja. SVN habe ich schon totgespielt, nun muss was neues, experimentelleres her. Mercurial war auch schon, vielleicht beizeiten mal Bazaar-NG oder darcs

Kann ich irgendwann machen, allerdings glaube ich sowieso nicht, das das jemand zu irgendwas verwenden will, so interessant ist der Code nicht.
Interessantere Codeschnippsel sind sowieso in meinem seperaten SVN-Repository.
jens hat geschrieben:Zu 1. Achso... Du meinst ist nutzte deinen Dienst, so wie ein öffentlicher Paste Dienst... Ich dachte immer es wäre nur eine Art Demo...
Es ist eigentlich beides. Es ist eine Spielwiese für neue Ideen sowie ein mehr oder weniger öffentlicher dienst. Zum Beispiel lösche ich die URLs bei
Shorty nicht. Mag aber sein, das das ganze irgendwann auf meine eigene Domain umzieht, wobei aber die Daten mitgenommen werden sollten.
jens hat geschrieben:Zu 2. Wie ist die DB Anbindung gelöst?
Über das Django-ORM. Ist zwar weniger flexibel als SQLAlchemy, aber es hat eine angenehme API mit der sich gut und vergleichsweise einfach arbeiten lässt.
Verfasst: Mittwoch 15. November 2006, 21:35
von jens
Bin nun ein wenig weiter... Ich hab mich immer gewundert das manche daten kaputt sind, nach dem download, und manche nicht...
Nun erstelle ich eine MD5 bevor die Daten in die DB kommen. Die MD5 wird als Metadaten abgespeichert.
Dann hab ich eine Funktion die eine neue MD5 von den Daten in der DB erstellt und mit der gespeicherten vergleicht.
Nach ein wenig rumprobieren, ist mir aufgefallen, das im Grunde Textdateien einwandfrei gespeichert werden, es sei denn es sind Sonderzeichen (Umlaute) drin...
Das hat mich auch die Idee gebracht einfach alles mit base64 zu bearbeiten.
Siehe da, alle Daten sind immer korrekt.
Verfasst: Donnerstag 16. November 2006, 10:36
von jens
So, nun ist es fertig. Und siehe da, die Grenze:
Nun geht's bis ca. 870KB, bei größeren Uploads kommt ein Traceback mit "MySQL server has gone away" Shocked
ist nun auch verschwunden!
7MB hochladen hat funktioniert
Wenn man es allerdings übertreibt kommt:
Got a packet bigger than 'max_allowed_packet' bytes
Nun muß ich mal rausfinden, wie man die Größe herraus bekommt...
Durch base64 hat man allerdings einen overhead von 33%.
Man muß auch beachten, das nach dem Löschen einer hochgeladenen Datei die Tabelle optimiert wird, damit der Speicherplatz auch wirklich freigegeben wird. Aber das ist auch schon Implementiert und funktioniert...
Verfasst: Donnerstag 16. November 2006, 10:37
von Blattlaus
jens hat geschrieben:Nach ein wenig rumprobieren, ist mir aufgefallen, das im Grunde Textdateien einwandfrei gespeichert werden, es sei denn es sind Sonderzeichen (Umlaute) drin...
Das hat mich auch die Idee gebracht einfach alles mit base64 zu bearbeiten.
Siehe da, alle Daten sind immer korrekt.
Base64 ist zwar eine Lösung für sowas, allerdings erzeugt das massig Overhead. Wenn du mit Umlauten ein Problem hast, hast du vermutlich eine Zeichensatzproblem. Ich nehme an Anwendung und DB verwenden nicht den gleichen Zeichensatz, also müsstest du beim lesen und holen konvertieren.
Verfasst: Donnerstag 16. November 2006, 11:22
von jens
jens hat geschrieben:Got a packet bigger than 'max_allowed_packet' bytes
Nun muß ich mal rausfinden, wie man die Größe herraus bekommt...
Erledigt:
http://pylucid.net/trac/changeset/574 
Nun wird die MySQL Variable ausgelesen und angezeigt.
Und gleich noch ein Update
http://pylucid.net/trac/changeset/575 hinterher. Dann wird der base64 overhead direkt mit der max_upload_size einbezogen.
Der Upload Vorgang wird direkt abgebrochen, wenn self.request.environ["CONTENT_LENGTH"] größer als der ermittelte max_upload_size ist
Wäre natürlich schön, wenn man es noch früher in colubrid abbrechen könnte!
EDIT: Ach noch was... Bei 1blu kann ich so immerhin 10.6 MB hochladen

Lokal ist mein MySQL Server so eingestellt, das nur 675.2 KB gehen...
EDIT2: Download hier:
http://pylucid.htfx.eu/index.py/PluginsDownload/ 
Verfasst: Donnerstag 16. November 2006, 11:31
von jens
Blattlaus hat geschrieben:Base64 ist zwar eine Lösung für sowas, allerdings erzeugt das massig Overhead. Wenn du mit Umlauten ein Problem hast, hast du vermutlich eine Zeichensatzproblem. Ich nehme an Anwendung und DB verwenden nicht den gleichen Zeichensatz, also müsstest du beim lesen und holen konvertieren.
Der Overhead wir einberechnet, wie du im Vortigen Posting nachlesen kannst

Ist natürlich verschenkter Platz...
Am Encoding kann es IMHO nicht liegen. BLOBs werden ohne Encoding hinterlegt:
BLOB-Spalten haben keinen Zeichensatz
http://dev.mysql.com/doc/refman/5.1/de/blob.html
Deswegen hab ich extra in meinem DBwrapper einen raw_cursor eingebaut, damit ich auch das automatische Zeichensatz Encoding im PyLucid-DBwrapper umgehe. Dennoch hat es nicht geklappt...