MySQLdb und BLOB >64KB Grenze???

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
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?
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ja, ich weiß. Für den Einsatzzweck ist das allerdings IMHO OK ;)

LONGBLOB ist es wohl ;) Dank dir!

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

So, hab nun LONGBLOB genommen... Nun geht's bis ca. 870KB, bei größeren Uploads kommt ein Traceback mit "MySQL server has gone away" :shock:

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 ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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 ?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
jens hat geschrieben:Auf http://django.benitum.de/gavril/ gibt echt wenig Info's.
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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Nutz doch zumindest SVN oder was ähnliches... Wo man nachschauen kann...

Aber gut, da es PostgreSQL nutzt ist es eh nix für mich ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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 ;)
  1. Du kannst für deine Bookmarks d.b.d verwenden, dafür ist es eben da
  2. Gavril ist nicht an eine bestimmte Datenbank gebunden. Es funktioniert mit PostgreSQL, MySQL, SQLite usw. Ich nutze eben PostgreSQL.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Blattlaus
User
Beiträge: 55
Registriert: Donnerstag 24. August 2006, 08:55

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.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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/ :lol:

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten