Lists: | pgsql-de-allgemein |
---|
From: | "Tim Frießinger" <Tim(dot)Friessinger(at)gmx(dot)net> |
---|---|
To: | pgsql-de-allgemein(at)postgresql(dot)org |
Subject: | Problem PL/Python-Stored Procedure und BYTEA |
Date: | 2006-11-08 08:49:23 |
Message-ID: | 20061108084923.279730@gmx.net |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-de-allgemein |
Hallo miteinander!
Ich bin neu hier und hoffe, dass ich mich mit meinem Problem hier an die richtige Mailing-Liste wenden.
Ich bastle seit einiger Zeit schon an einer Bilder-Datenbank. Die Bilder liegen dabei auf dem Filesystem, die Meta-Informationen (Beschreibung des Bildes usw...) dazu werden in einer PostgreSQL-Datenbank gespeichert. Da ich gerne das Benutzer-Management von PostgreSQL nutzen möchte, sieht mein Ziel so aus:
Auf das Bilderverzeichnis im Filesystem soll nur der Benutzer "postgres" Zugriff haben, sprich ein normaler Systembenutzer (ich benutze Ubunut Linux) soll keine Möglichkeit haben, da manuell hinein zu kommen.
Wenn ein User meiner Bilder-Datenbank (erhält einen stark eingeschränken PostgreSQL-Account) von der Datenbank her die Rechte hat, ein Bild einzusehen, soll er es von PostgreSQL "durchgereicht" bekommen.
Den Zugriff auf das Dateisystem für PostgreSQL habe ich mit Stored Procedures in Python realisiert, Rückgabe-Typ ist BYTEA.
Meine erste Version sah so aus:
####
CREATE FUNCTION read_file(TEXT) RETURNS BYTEA AS '
import os
path = args[0].replace(''/'', os.sep)
# öffne Datei im binären Lese-Modus
fp = open(path, "rb", 0)
ret = fp.read()
fp.close()
return ret
' LANGUAGE plpythonu;
#####
Das Problem war hier dass die Rückgabe offenbar nicht escaped war, und so immer nur ca. 4 Byte durchgereicht wurden. Nach einiger Recherche habe ich ein Stück Python-Code gefunden, welches die Rückgabe präpariert hat:
####
CREATE FUNCTION read_file2(TEXT) RETURNS BYTEA AS '
import os
path = args[0].replace(''/'', os.sep)
# öffne Datei im binären Lese-Modus
fp = open(path, "rb", 0)
ret = fp.read()
fp.close()
# escape String
return ''.join(['\\%03o' % ord(x) for x in ret])
' LANGUAGE plpythonu;
#####
Damit hat es theoretisch schon mal geklappt: Ich konnte über einen Aufruf dieser Stored Procedure mittels eines Java-Programmes (JDBC) die Binärdaten eines Bildes auslesen, mit dem Java-Programm wieder zurück in eine Datei schreiben und hatte damit eine Kopie des Bildes.
So, nach dieser langen Ausschweifung nun mein eigentliches Problem:
Nach dem die Sache mit einem Bild geklappt hat, hat mich wohl der Großenwahn gepackt und ich dachte mir, dass ich ja vielleicht nicht nur Bilder, sondern generell Media-Daten, also auch Videos etc... über meine Datenbank verwalten könnte. Also habe ich mal eine ca. 40 MB große Datei über diesen Weg kopieren wollen.
Das Resultat war, dass meine Festplatte angefangen hat wie wild zu rödeln und mein komplettes System unerträglich langsam wurde. Ich konnte nicht mal mehr ne Shell öffnen um den Prozess abzuschießen. Nach mind. 5 Minuten hab ich meinen Computer dann neugestartet. Dann hab ich mich mal mit immer großer werdenden Dateien vorgetastet. So bis ca. 10 MB konnte ich eine Datei auf diesem Wege kopieren, danach ging die Rödelei dann wieder los.
Aber irgendwie kann ich mir es nicht vorstellen, dass man auf diesem Wege maximal 10 MB durch das DBMS reichen kann. Ich habe den Verdacht dass das Escapen der Rückgabe in Python die Probleme bereitet, aber sicher bin ich mir nicht.
Hat sich vielleicht jemand anderes schon mit Ähnlichem beschäftigt und kann mir einen Tipp geben, wie ich das anders lösen könnte?
Ich würde eigentlich gerne bei Python als PL bleiben, weil es da eine sehr einfache Bibliothek gibt, mit der ich Thumbnails von Bildern erzeugen kann (was ich gerne hätte).
Würde mich sehr freuen, wenn mir jemand helfen könnte! :)
Danke für eure Aufmerksamkeit & Gruß,
Tim
--
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer
From: | Peter Eisentraut <peter_e(at)gmx(dot)net> |
---|---|
To: | pgsql-de-allgemein(at)postgresql(dot)org |
Cc: | "Tim =?iso-8859-1?q?Frie=DFinger?=" <Tim(dot)Friessinger(at)gmx(dot)net> |
Subject: | Re: Problem PL/Python-Stored Procedure und BYTEA |
Date: | 2006-11-08 15:36:36 |
Message-ID: | 200611081636.37252.peter_e@gmx.net |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-de-allgemein |
Am Mittwoch, 8. November 2006 09:49 schrieb Tim Frießinger:
> Nach dem die Sache mit einem Bild geklappt hat, hat mich wohl der
> Großenwahn gepackt und ich dachte mir, dass ich ja vielleicht nicht nur
> Bilder, sondern generell Media-Daten, also auch Videos etc... über meine
> Datenbank verwalten könnte. Also habe ich mal eine ca. 40 MB große Datei
> über diesen Weg kopieren wollen. Das Resultat war, dass meine Festplatte
> angefangen hat wie wild zu rödeln und mein komplettes System unerträglich
> langsam wurde.
Ich kenne zwar die Interna von Python nicht, aber ich kann mir gut ausmalen,
wie bei einer solchen Implementierung die ganze Datei etwa drei bis sechs Mal
im Speicher kopiert wird. Am effizientesten wird das, wenn man die Daten als
bytea in der Datenbank speichert und im binären Protokollmodus abruft. Dann
hat man maximal eine Kopie im Speicher.
--
Peter Eisentraut
http://developer.postgresql.org/~petere/
From: | "Tim Frießinger" <Tim(dot)Friessinger(at)gmx(dot)net> |
---|---|
To: | pgsql-de-allgemein(at)postgresql(dot)org |
Subject: | Re: Problem PL/Python-Stored Procedure und BYTEA |
Date: | 2006-11-09 08:31:17 |
Message-ID: | 20061109083117.239930@gmx.net |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-de-allgemein |
Hallo und vielen Dank für die schnelle Antwort!
> Ich kenne zwar die Interna von Python nicht, aber ich kann mir gut
> ausmalen,
> wie bei einer solchen Implementierung die ganze Datei etwa drei bis sechs
> Mal
> im Speicher kopiert wird. Am effizientesten wird das, wenn man die Daten
> als
> bytea in der Datenbank speichert und im binären Protokollmodus abruft.
> Dann
> hat man maximal eine Kopie im Speicher.
Ursprünglich hatte ich das auch so vor, dass ich die Bilder meiner Bilder-Datenbank direkt als BYTEA in der Datenbank ablege. Ich bin dann aber von der Idee abgekommen, da ich es ganz praktisch finde, wenn die ganzen Bilderdateien weiterhin direkt im Filesystem verfügbar sind und man (zumindest als root) auch direkt an die Bilder rankommt, ohne den Umweg über die Datenbank zu machen. Kategorien und Alben welche man in meiner Bilderdatenbank anlegt, werden durch Stored Procedures auch direkt ins Filesystem übertragen, dieses Prinzip würde ich gerne beibehalten.
Vielleicht gelingt es mir ja noch eine bessere Escape-Möglichkeit zu finden, welche nicht so Speicherhungrig ist und das System "tot-swappen" tut.
Danke & Gruß,
Tim Frießinger
--
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer