bild datei in db speichern

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Nebelhom
User
Beiträge: 155
Registriert: Mittwoch 19. Mai 2010, 01:31

Hi,

in einem hobby projekt von mir muesste ich mehrere eintraege bestehend aus mehreren strings und einem bild (jpeg, bmp, png etc) speichern, damit ich auf diese zu einem spaeteren zeitpunkt wieder zu greifen kann.

Jetzt bin ich wirklich nicht die Leuchte, was datenbanken angeht und frage mich 2 fragen:

1. welche datenbank waere dafuer geeignet?

und

2. wie speichere ich dieses bild?


Fuer 1. waere ich einfach fuer tipps u persoenliche erfahrungen dankbar, da ich die zeit, die ich aufwende, um mich einzulesen minimieren moechte. Habe schonmal couchdb und mongodb versucht, aber da fand ich persoenlich die doku fuer die python anbindung duerftig (besonders was den fall mit dem bild angeht)

was 2. angeht: kann man das bild so wie es ist speichern oder muss man das erst in ein anderes format konvertieren (blob?)? ich habe es mal versucht via PIL in einen string zu machen, aber die konvertierung zurueck zu einem bild war gelinde gesagt nicht erfolgreich (bilddatei mit randomly distributed pixels)

ich danke schonmal fuer die hilfe

Johannes
querdenker
User
Beiträge: 424
Registriert: Montag 28. Juli 2003, 16:19
Wohnort: /dev/reality

Hej! Abhängig von der Größe der Bilder würde ich mir das gut überlegen ob ich Bilder in einer DB speichere.
Gerade für binäre Objekte deren Größe unbekannt ist (oder die aus der DB ausgelesen, bearbeitet und dann wieder gespeichert werden sollen) macht es meiner Meinung nach eher Sinn diese Daten in einer Struktur direkt auf der Festplatte zu speichern und nur die Pfadreferenz auf die Datei in der DB zu speichern.

Ansonsten
zu 1) Jede DB die in der Lage ist Binärdaten zu speichern
zu 2) Schau dir mal die Dokumentation von kinterbasdb an. Das ist die python-Schnittstelle für Firebird/Interbase

hth, m.
I'm not getting paid for being Mr. Nice Guy!
Benutzeravatar
noisefloor
User
Beiträge: 4149
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

da CouchDB "attachements" direkt unterstützt ist es damit IMHO am einfachsten, unter Verwendung des couchdb Moduls:

Code: Alles auswählen

from couchdb import Server
server = Server()
db = server['meine_db']
doc = db['mein_doc']
db.put_attachment(doc,'mein_anhang.xyz',filename='mein_anhang.xyz')
Fertig! :-) Doku ist hier.

Wobei du natürlich bedenken musst, was du noch speichern willst und wie die anderen Einträge pro Dokument aussehen und abgefragt werden sollen.

Wenn du eine relationale DB brauchst -> ich bin sicher, Google, findet min 1 Mio Treffer, wie man ein BLOB in MySQL speichert... ;-)

Gruß, noisefloor
3ff
User
Beiträge: 191
Registriert: Dienstag 22. Dezember 2009, 12:54
Wohnort: Odenwald Sued-Hessen

@Nebelhorn,
Du müßtest schon genauer werden, warum Du ein Bild in einer Datenbank speichern willst?
Willst Du vielleicht den Titel der Bilder in einer relationalen datenbank speichern um die Bildertitel dann suchen, sortiern oder sonstwas zu können?
Dann müßte auch auf die einzelnen Bilder zugegriffen werden können!(über 1 datenfeld) :?:
Das wäre dann sowas wie 1 Katalog!
Grüße Fritz :?: :?:
Nebelhom
User
Beiträge: 155
Registriert: Mittwoch 19. Mai 2010, 01:31

hi guys,

vielen danke fuer euer feedback, ich habe jetzt auf jeden fall eine besseren starting point als vorher. das mit dem blob speichern ist so eine sache. Ich glaube, ich habe noch nicht mal wirklich die grundlagen von datenbanken verinnerlicht, weshalb ich mich gerade versuche noch schlauer darueber zu machen. Deswegen uebrigens auch die frage mit dem Bild.

So bloed das jetzt auch klingen mag, aber ich versteh ja schon nicht mal richtig wie ich eine datei in eine database reinbekomme, weil wenn ich den pfad als string angebe, wird ja der string gespeichert. Das ist so basic, dass ich mir das eigentlich selber erarbeiten will (also keine pointers). Deshalb habe ich lieber nur nach tipps gefragt, nach welchen schluesselwoertern ich suchen soll.

@noisefloor: wie ich sehe, hast du mir das via couchdb schon erklaert :) Danke dafuer.

@3ff sorry dafuer. ich versuche meine threads generell nur auf das grundlegendste zu reduzieren und euch nicht mit unnoetigem detail nerven.

Die application ist eine kleine hilfe fuer organische chemiker beim schreiben des experimentals in publikationen, da es noch keine frei verfuegbare software gibt, die das fuer dich macht. das ewige umschalten von kursiv auf normal auf fettgedruckt auf anderen schriftfont und superscript usw ist wirklich nervig und hat mich waehrend meines PhDs fast in den Wahnsinn getrieben.

deswegen schreibe ich gerade an einem program, dass die analytischen daten fuer verschiedene komponente speichert und dann ausgibt, wie man es will, je nach peer-reviewed journal. deswegen die database, die je nach analytischer technik die daten als strings speichern soll (quasi name: compound; analytical tech.: title: 1H nmr; dann daten; title: mass spec: wieder daten etc).

Das bild ist eigentlich eher voruebergehender natur, weil ich noch nicht in der lage bin, ein chemistry drawing program in einer meiner applications zu embedden und zu speichern (mit chemdraw kann man das alles relativ schnell zeichnen und als bild speichern). Bilder sind unablaesslich ab einer bestimmten komplexitaet des molekuels, weil die IUPAC naming convention sehr komplex ist. deswegen das bild zusammen mit den obenerwaehnten daten beim compound speichern. Als Beispiel: Kein organischer chemiker, den ich kenne, wird auf anhieb wissen, ob er jemals

(2S)-2-[(4-{[(2-amino-4-hydroxypteridin-6-yl)methyl]amino}phenyl)formamido]pentanedioic acid

benutzt hat. Wenn er dann aber das bild der struktur von Vitamin B9 sieht, ist die wahrscheinlichkeit groesser, dass er es erkennt.

Ich hoffe, das hat deine frage beantwortet. Das bild soll zusammen mit den anderen daten mitgeliefert werden, damit leute auf den ersten blick sehen an welchem molekuel sie arbeiten.

War das jetzt zu viel information? ich will hier keinen langweilen.

Gruss

Johannes
Benutzeravatar
noisefloor
User
Beiträge: 4149
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

von der Struktur der Daten her passt da IMHO schon CouchDB bzw. eine dokumenten-orientierte Datenbank sehr gut. Ein Dokument pro Komponente.

Bzgl. BLOB: Du musst die Bilddaten, die bei jpg, png usw. ja binär vorliegen, in einen binären String umwandeln und diesen dann in die DB schreiben. Bei Holen läuft es dann umgekehrt: du holst den binären String und schreibst diesen in eine Datei.

Was ist denn am Ende bei deiner Applikation das Ausgabe-Format? HTML? PDF? Text-Datei? ...?

Gruß, noisefloor
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Ich habe den Thread nur kurz überflogen, daher verzeihe bitte ggf. doppelte Anmerkungen.

Wenn es möglich ist, dann solltest du von Bildern in einer Datenbank absehen, da du auf diesen im Prinzip keine sinnvollen Abfragen machen kannst. Hinzu kommt, dass es natürlich nicht ganz so performant ist, wahrscheinlich aber vernachlässigbar. Ich würde dir dazu raten, lediglich Dateinamen in der DB zu speichern und die Bilder in einem extra Ordner halten. Für so etwas ist gerade das Dateisystem gedacht. Ein wenig kritisch kann es werden, wenn die Datenbank und Bilder nicht mehr synchronisiert sind. Dort muss etwas zusätzlicher Aufwand betrieben werden.

Solltest du doch die Bilder direkt abspeichern wollen, dazu gibt es gerade einen änlichen Thread. Damit sollte sich dein PIL-Problem lösen.

Empfehlen würde ich dir PostgreSQL oder SQLite. Letzteres ist bei Python dabei und muss nicht extra installiert werden, hat aber auch seine Grenzen. Etwas einfacher zu Benutzen wird es meistens noch durch ein ORM wie SQLAlchemy, da solltest du vielleicht noch einen Blick drauf werfen.

Sebastian
Das Leben ist wie ein Tennisball.
Nebelhom
User
Beiträge: 155
Registriert: Mittwoch 19. Mai 2010, 01:31

EyDu hat geschrieben: Wenn es möglich ist, dann solltest du von Bildern in einer Datenbank absehen, da du auf diesen im Prinzip keine sinnvollen Abfragen machen kannst. Hinzu kommt, dass es natürlich nicht ganz so performant ist, wahrscheinlich aber vernachlässigbar. Ich würde dir dazu raten, lediglich Dateinamen in der DB zu speichern und die Bilder in einem extra Ordner halten. Für so etwas ist gerade das Dateisystem gedacht. Ein wenig kritisch kann es werden, wenn die Datenbank und Bilder nicht mehr synchronisiert sind. Dort muss etwas zusätzlicher Aufwand betrieben werden.
Hi. danke fuer die warnung. Was meinst du mit "sinnvollen Abfragen"? kann man die bilder nicht verlaesslich aus dem gespeicherten format wieder herstellen?

hmmm... wenn ich das richtig verstanden habe, dann sollte ich die Bilder in einem unterverzeichnis speichern und nur den Pfad als string in die datenbank einfuegen. Sehe ich das richtig?

Was ist dann der vorteil an SQLite oder couchdb ueber, sagen wir, dem pickle modul (das ja eigentlich wie ein dictionary funktioniert)? Ich habe gemerkt, dass die meisten benutzer dieses forums pickle nicht besonders schaetzen. weshalb ist das so?

Wenn die sache mit dem bild nicht waere, haette ich naemlich pickle verwendet.
EyDu hat geschrieben: Empfehlen würde ich dir PostgreSQL oder SQLite. Letzteres ist bei Python dabei und muss nicht extra installiert werden, hat aber auch seine Grenzen. Etwas einfacher zu Benutzen wird es meistens noch durch ein ORM wie SQLAlchemy, da solltest du vielleicht noch einen Blick drauf werfen.

Sebastian
Danke fuer deinen Vorschlag (und alle davor), ich werde mir die erwaehnten DBs alle mal anschauen und dann eine passende auswaehlen. Die auswahl konnte auf jeden fall eingeengt werden ;). Es ist immer fies wenn man ein ueberangebot an sachen hat, aber keine ahnung was gut ist und was nicht (bzw. in welchen bestimmten faellen nuetzlich).
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Mit "sinnvolle Abfragen" meine ich, dass du wahrscheinlich niemals mit den mitteln einer relationalen Datenbank in einem Bild suchen möchtest. Meistens sollen nur die enthaltenen Daten in irgend einer Form geliefert werden. Korrekt sind sie bei der Abfrage auf jeden Fall.

Der Vorteil einer "echten" Datenbank gegenüber pickle ist, dass man relativ einfach Anfragen an die Datenbank stellen kann, welche sonst selber geschrieben werden müssen. Das pickle-Modul ist übrigens etwas mehr als ein Dictionary: dort können beliebige (bis auf ein paar Ausnahmen) Objekte abgelegt werden. Möchtest du nur ein Dictionary auf Dateiebene, dann bietet sich shelve an. So unebliebt ist pickle auch nicht, es setzt sich allerdings immer mehr json durch, da dieses über Python-Grenzen hinweg verwendet werden kann.
Nebelhorn hat geschrieben:hmmm... wenn ich das richtig verstanden habe, dann sollte ich die Bilder in einem unterverzeichnis speichern und nur den Pfad als string in die datenbank einfuegen. Sehe ich das richtig?
Ja, genau. Natürlich nur den relativen Pfad oder eine id, mittels welcher man auf die Datei schließen kann.

Sebastian
Das Leben ist wie ein Tennisball.
Benutzeravatar
noisefloor
User
Beiträge: 4149
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

der Nachteil von Bildern direkt in der DB ist, dass die DB sehr schnell sehr groß wird. Dabei geht es nicht unbedingt um den Platz, den die DB auf der Platte belegt (schließlich nehmen die Bilder direkt auf der Platte auch Platz in Anspruch ;-) ), sondern dass der Zugriff auf die DB ggf. langsamer wird.

Gruß, noisefloor
Nebelhom
User
Beiträge: 155
Registriert: Mittwoch 19. Mai 2010, 01:31

naja, das format wie ich die daten speichere, wollte ich mir erst ueberlegen, wenn ich weiss, welche moeglichkeiten ich habe, aber ich hatte immer das gefuehl, dass ich das in einer art persistent dictionary speichern werde, obwohl das mitunter sehr verschachtelt werden kann... hmmm... vielleicht haettet ihr da ein paar tipps auf lager.

Jetzt da es erscheint, dass fuer bilder besser nur der pfad gespeichert wird, ist es wohl nur eine ansammlung von strings. ich bin mir da noch nicht so ganz gruen aber ich denke ein dictionary waere am besten.

Die struktur das ganzen waere ungefaehr so:

Name der gespeicherten datei

kategorien:
Name von Compound
Daten Analytische technik 1
Daten Analytische technik 2
Daten Analytische technik 3
etc...

Die haben dann wieder unterkategorien; zum beispiel eines hat dann werte die alle zusammengehoeren z.B.

Shift: 1.23; Protons: 3H; multiplicity: d; Coupling constants: J=7.6 Hz; Assignment: Me

Da mache ich dann zum beispiele ein tuple raus. und so kommt dann die struktur

Code: Alles auswählen

{"gespeicherterName1":{"Name":"xyz","AnalyTech1":("Werte"),"AnalyTech2":("Werte"),etc},"gespeicherterName2":{"Name":"abc","AnalyTech1":("Werte"),"AnalyTech2":("Werte"),etc...}...}
Ist das zu kompliziert und ich mache mir damit auf lange sich das leben schwer oder passt das so schon? Ist shelve dafuer geeignet oder ist da eine andere bessere fuer geeignet?

Vielen Dank fuer die Hilfe. Ich sehe dass ich mich mal wieder ins tiefe Eck des Schwimmbads geschubst habe...
3ff
User
Beiträge: 191
Registriert: Dienstag 22. Dezember 2009, 12:54
Wohnort: Odenwald Sued-Hessen

@Johannes alias Nebelhorn,
Alles klar, Du brauchst Dich nicht entschuldigen.
Jeder fängt mal an und manche können nie aufhören.
Was python angeht, so ist dies Forum schon richtig!
Ich bekomme auch mal heiße Ohren hier im Forum, 8) damit muß mal leben!
Guude! Fritz 8) 8)
Nebelhom
User
Beiträge: 155
Registriert: Mittwoch 19. Mai 2010, 01:31

@3ff

Ich wollte es vorhin nicht sagen, aber es ist NebelhoM ;). War frueher Nebelhorn, aber wegen meiner Sauklaue (by pen and paper rollenspielen) haben alle Nebelhom gelesen ;)

Waere lustig wenn sich das jetzt wieder rueckverwandelt in Nebelhorn, weil sich wieder jemand verliest ;)

Forumsspezifisch:
Es ist manchmal relativ schwer fuer mich zu unterscheiden zwischen relevanten Daten und netter zusatzinformation. da ich selber weiss, wie nervig es manchmal ist, einen eintrag durchzulesen, bei dem jemand viiiieeeel zu weit ausholt, versuche ich das am anfang zu reduzieren. naja, meist kommt dann der wunsch nach mehr info... not perfect yet ;)

Gruss NebelhoM 8)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Bevor du mit verschachtelten Dictionaries spielst, solltest du wohl eher auf eigene Klassen umsteigen. Daten, welche du in jedem Fall benötigst, werden zu Attributen. Optionale Informationen werden hingegen entweder mit None belegt oder du führst dafür ein extra Attribut ein, welches selbst ein Dictionary ist. Die zweite Lösung ist relative praktisch, da so einige Sonderfälle umgehen kannst, falls die Informationen nicht vorliegen. Das kannst du dann sehr einfach mit einem ORM umsetzen oder an mittels pickle.
Nebelhom hat geschrieben:Ich wollte es vorhin nicht sagen, aber es ist NebelhoM ;).
Das passiert wohl, wenn man mal nicht den Quote-Button verwendet :roll:

Sebastian
Das Leben ist wie ein Tennisball.
Nebelhom
User
Beiträge: 155
Registriert: Mittwoch 19. Mai 2010, 01:31

EyDu hat geschrieben:Hallo.

Bevor du mit verschachtelten Dictionaries spielst, solltest du wohl eher auf eigene Klassen umsteigen. Daten, welche du in jedem Fall benötigst, werden zu Attributen. Optionale Informationen werden hingegen entweder mit None belegt oder du führst dafür ein extra Attribut ein, welches selbst ein Dictionary ist. Die zweite Lösung ist relative praktisch, da so einige Sonderfälle umgehen kannst, falls die Informationen nicht vorliegen. Das kannst du dann sehr einfach mit einem ORM umsetzen oder an mittels pickle.
Nebelhom hat geschrieben:Ich wollte es vorhin nicht sagen, aber es ist NebelhoM ;).
Das passiert wohl, wenn man mal nicht den Quote-Button verwendet :roll:

Sebastian
Hey, daran habe ich noch gar nicht gedacht! das ist wirklich, um einiges uebersichtlicher... ich werde mir das mal ueber das WoE anschauen.

Ich denke, meine Fragen zu dem Thema sind jetzt alle beantwortet oder es gibt genug info, um selbst eine antwort zu finden.

Ich danke euch allen fuer die prompte hilfe und die diskussion. Das hat mir ziemlich geholfen, mein Program vorzustrukturieren.

Gruss

Johannes
Benutzeravatar
noisefloor
User
Beiträge: 4149
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
vielleicht haettet ihr da ein paar tipps auf lager.
Hier passt auch XML IMHO ganz gut.

Wenn es eine DB sein soll - eine relationale DB mit ORM oder eine dokumenten-orientierte DB. DB brauchst du aber auch IMHO nur, wenn du gezielt Daten suchen musst oder selektieren willst.

Gruß, noisefloor
3ff
User
Beiträge: 191
Registriert: Dienstag 22. Dezember 2009, 12:54
Wohnort: Odenwald Sued-Hessen

Hallo Johannes,
ich hab was Interessantes gefunden, in dem Softwarepool von Nokia.
es gibt 1 tarball von Nokia
qt-everywhere-opensource-src-4.6.3-blabla
den hab ich mir kürzlich von der Nokia-Homepage "gesaugt"
Schlimmes Wort!
Wenn Du den tarball auspackts, installierst und durchsuchst,dann gibts da ein Unterverzeichnis sql/drilldown
da ist ein Beispiel (in Cpp ) wie man Bilder in Datenbanken speichert.
Es ist genauso, wie ich es vermutet habe:
1) Die Bilder liegen als *.png Dateien vor
2) In der (bei meiner Postgresql) gibt es Verweise zu den Bildern
3) Dadurch kann man gewissermassen 1 Katalog von Bildern erzeugen, verwalten, umsotieren etc.
Anders wird da auch kein Schuh draus.
Meine 7.5 Mio pixel Digi-Kamera erzeugt Bilder als jpg-Files, wo jedes File mal 2 bis 2.5 Mio Bytes hat.
Wenn Du jetzt-sagen wir- 5000 Bilder hast und die alle auf 1 Platte speichern wills, dann sind das (ist zu spät heute dafür) xyz-Giga Byte.
Die datenbank dazu wäre natürlich ERHEBLICH kleiner und durch ein indexiertes Suchen findet man das gewünschte Bild schnell.
So kann man im Online-Verkauf arbeiten.
Das Beispiel ist sehr umfangreich, das umzustricken auf PyQt4 oder PySide ist viel Arbeit.
Das müßte eigentlich Nokia machen, wobei ich wieder beim Thema wäre.
Rat von mir: Fotografiere Deine Bilder ab und speichere sie auf 1 digitalen Datenträger
Ich hab leider keine Zeit, um das in Python umzustricken, weil ich wieder weg muß.
Grüße und viel Spaß wünscht
Fritz 8) 8)
Antworten