Firebird BLOB Bilddaten Export

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Habe eine Firebird DB, in der Bilddaten in einem BLOB-Feld liegen. Habe mir mal FlameRobin gezogen und in der DB rumgespielt. Leider zeigt der mir bei meinem Query

Code: Alles auswählen

SELECT image FROM table WHERE eggs=spam
nur das hier an:

[...]

Der kann die BLOB-Daten also nicht darstellen, noch nicht mal als Plaintext. Die Frage ist, wie kann ich die exportieren? Würde ja gern ein Python-Tool dafür basteln. Hat jemand mal ne Kurzanleitung für den Firebird Verbindungsaufbau, den Query und das Speichern als (JPEG-) Bild? Interessiert mich mal... :D
BlackJack

Wie willst Du Binärdaten auch als Plaintext anzeigen!?

Welchen Typ hat das Ergebnis denn?
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Na ich kann mir doch einfach eine Bilddatei im Texteditor anzeigen lassen. Macht zwar visuell keinen Sinn, aber der String kann ja wiederum als Bild geschrieben werden...

Den Ergebnistyp zeigt mir FlameRobin nicht an. Was genau meinst du eigentlich damit? Es steht nur eckige Klammer auf, drei Punkte und eckige Klammer zu da.
BlackJack

Ob man beliebige Binärdaten in einem Texteditor anzeigen lassen kann, kommt stark auf den Editor an.

Ich meinte was ``print type(blob)`` ergibt, wenn `blob` ein Objekt ist, was von der Datenbank kommt. Ich dachte Du programmierst selbst etwas in Python und bekommst diese Darstellung.
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

siehe oben:
droptix hat geschrieben:at jemand mal ne Kurzanleitung für den Firebird Verbindungsaufbau, den Query und das Speichern als (JPEG-) Bild?
Ich weiß nicht welches Modul eine Verbindung zur Firebird-DB aufbauen kann. Hatte bislang mit Firebird absolut nix am Hut :lol:
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

droptix hat geschrieben:Ich weiß nicht welches Modul eine Verbindung zur Firebird-DB aufbauen kann.
Hi droptix!

- http://www.python-forum.de/topic-6848.html
Suche nach "Firebird"

- http://kinterbasdb.sourceforge.net/dist_docs/usage.html
- http://kinterbasdb.sourceforge.net/dist ... conv_blobs

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Hum, nachdem ich kinterbasdb wegen SQLObject installiert hab, erhalte ich beim Verbindungsaufbau folgenden Fehler:
Python Interpreter hat geschrieben:C:\PROGRA~1\Python24\lib\site-packages\sqlobject-0.8.2-py2.4.egg\sqlobject\__ini
t__.py:19: DeprecationWarning: FirebirdConnection is deprecated; use connectionF
orURI("firebird://...") or "from sqlobject.firebird import builder; FirebirdConn
ection = builder()"
_warn('FirebirdConnection is deprecated; use connectionForURI("firebird://..."
) or "from sqlobject.firebird import builder; FirebirdConnection = builder()"')
Traceback (most recent call last):
File "test.py", line 3, in ?
connection = sqlobject.FirebirdConnection("192.168.0.187", "WINORDER.FDB")
File "c:\programme\python24\lib\site-packages\SQLObject-0.8.2-py2.4.egg\sqlobj
ect\__init__.py", line 20, in FirebirdConnection
return _firebird.builder()(*args, **kw)
File "c:\programme\python24\lib\site-packages\SQLObject-0.8.2-py2.4.egg\sqlobj
ect\firebird\firebirdconnection.py", line 18, in __init__
import kinterbasdb
File "C:\Programme\Python24\Lib\site-packages\kinterbasdb\__init__.py", line 1
09, in ?
import _kinterbasdb as _k
ImportError: DLL load failed: Das angegebene Modul wurde nicht gefunden.
Letzlich scheitert's aber direkt wegen dem kinterbasdb-Modul, oder? Meine Kiste: Windows. Mein Code:

Code: Alles auswählen

import sqlobject

connection = sqlobject.FirebirdConnection("192.168.0.187", "FILE.FDB")
BlackJack

Du könntest die Anweisung in der ersten Warnung befolgen, auch wenn dass das Problem wohl nicht beheben wird.

Wie hast Du `kinterbasdb` denn installiert?
querdenker
User
Beiträge: 424
Registriert: Montag 28. Juli 2003, 16:19
Wohnort: /dev/reality

Moin,
versuche erstmal, die Datenbank direkt über kinterbasdb anzuzapfen.
SqlObject und Firebird ist etwas hakelig.

Ich poste dir nachher nochmal 'ne Lösung, die habe ich in der Firma noch auf der Platte rumdümpeln.

Vom Prinzip sieht das aber so aus:

Code: Alles auswählen

import kinterbasb

pic=file('c:/pfad/zur/datei','wb')
con=kinterbasdb.connect(dsn='127.0.0.1:c:/pfad/zur/datenbank', user='username', pass='passwort')
cur=con.cursor()

stm='select blob from tabelle where id=123'
cur.execute(stm)
dump=cur.fetchall()
cur.close()
con.commit()
con.close()

pic.write(dump[0])
pic.close()
Code ist nicht getestet, da gerade an einer Linuxmaschine ohne FB

Ansonsten kannst du dir übrigens auch mal IBExpert ansehen, den gibt es in einer Light-Version kostenlos. Wir setzen den in der Pro-Variante ein, der ist echt gut.
hth, marcus
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

BlackJack hat geschrieben:Wie hast Du `kinterbasdb` denn installiert?
Na so: Der Installer ist dann fertig und ich hab losgelegt. So, hab's grad über die Systemsteuerung und Software wieder rausgekickt. Fehler wie erwünscht:
ImportError: No module named kinterbasdb
Dann nochmal neu installiert. Bringt nix (siehe unten).

Das import kinterbasdb und das password='password' waren falsch. Code:

Code: Alles auswählen

import kinterbasdb

pic=file('foo.jpg','wb')
con=kinterbasdb.connect(host='192.168.0.187', database='C:/Programme/Spam/Eggs.fdb', user='sysdba', password='masterkey')
cur=con.cursor()

stm='select IMAGE from MYTABLE where ID=123'
cur.execute(stm)
dump=cur.fetchall()
cur.close()
con.commit()
con.close()

pic.write(dump[0])
pic.close()
Das mit dem DSN geht natürlich auch. Trotzdem dieselbe Fehlermeldung:
Traceback (most recent call last):
File "test.py", line 1, in ?
import kinterbasdb
File "C:\Programme\Python24\Lib\site-packages\kinterbasdb\__init__.py", line 1
09, in ?
import _kinterbasdb as _k
ImportError: DLL load failed: Das angegebene Modul wurde nicht gefunden.
In den Zeilen 108 und 109 steht:

Code: Alles auswählen

# The underlying C module:
import _kinterbasdb as _k
querdenker
User
Beiträge: 424
Registriert: Montag 28. Juli 2003, 16:19
Wohnort: /dev/reality

Ich habe doch geschrieben, das der Code ungetestet ist.


So langsam stellt sich die Frage, wie du den Firebird installiert hast.
Hast du nur den FB-Client installiert oder den kompletten FB-Server?
Ist die fbclient32.dll im %SYSTEMROOT%\System32 vorhanden?

So und hier nochmal ein Beispiel, das funktioniert:

Code: Alles auswählen

#-*- coding: iso-8859-1 -*-
import kinterbasdb
raw_list=[]
con=kinterbasdb.connect(dsn='192.168.213.37:d:/database/cust01/bilder.fdb',
                        user='SYSDBA',
                        password='masterkey',
                        charset='WIN1252',
                        dialect=1)
cur=con.cursor()

stm="select id from t_bilder where t_bilder.sachverst = ''"

cur.execute(stm)
data=cur.fetchall()
for item in data:
    raw_list.append(item[0])
    
con.commit()
del data

for item in raw_list:
    helper=str(item)
    fstr='c:/citrix/cust01/' + helper + '.jpg'
    stm="select bild from t_bilder where id="+helper
    cur.execute(stm)
    tdata=cur.fetchall()
    data=tdata[0][0]
    fh=file(fstr,'wb')
    fh.write(data)
    fh.close()
    print stm

con.commit()
cur.close()
con.close()
Ist mal wieder, wie üblich, ein QnD-Hack für zwischendrin

mfg, querdenker
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

querdenker hat geschrieben:Ansonsten kannst du dir übrigens auch mal IBExpert ansehen
Jo, hab mir die Personal Edition besorgt. Damit sehe ich beim besagten Bild schonmal mehr als ein [...], nämlich ein Icon. Rechtsklick und "Copy cell value" bringt beim Einfügen ins Notepad allerdings nur die zwei Zeichen "xo". Bei anderen Bildern kommt da auch nur ganz kurzer Buchstabensalat. Mir fehlt da sowas wie ein "Save BLOB to file".

Letztlich muss ich aber trotzdem alle BLOBs rausholen, und zwar möglichst automatisiert. Daher wäre ein funktionierendes Python-Tool schon ganz praktisch. Frage mich, was mit dem C-Modul nicht stimmt. Es gibt folgende Datei:

C:\Programme\Python24\Lib\site-packages\kinterbasdb\_kinterbasdb.pyd

Das dürfte wohl schonmal das Modul sein, oder?
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

querdenker hat geschrieben:Ich habe doch geschrieben, das der Code ungetestet ist.
Jo, nichts für ungut. War nur ein Hinweis für die anderen Leser. Ich dank dir ja so schon wie verrückt für deine Hilfe :)
querdenker hat geschrieben:So langsam stellt sich die Frage, wie du den Firebird installiert hast.
Hast du nur den FB-Client installiert oder den kompletten FB-Server?
Ist die fbclient32.dll im %SYSTEMROOT%\System32 vorhanden?
Und da kommen wir der Sache doch schon näher! Auf dem Rechner mit dem Python-Script hab ich gar nichts von Firebird installiert. In einer virtuellen Maschine hab ich eine Software installiert, die Firebird als DB benutzt, also ist da der Server in Version 1.5 drauf.

Heißt also, ich brauch den Client auf dem Rechner mit dem Script? Woher kriege ich den einzelnen Client? Ich dachte beim Installieren von Firebird wird der Server draufgekracht... Ich habe die zwei DLLs `gds32.dll` und die neuere `fbclient.dll`. Reicht es, wenn ich die irgendwo hin kopiere?

Oder ich installiere Python einfach in der virtuellen Maschine.
querdenker hat geschrieben:Ist mal wieder, wie üblich, ein QnD-Hack für zwischendrin
Danke!
querdenker
User
Beiträge: 424
Registriert: Montag 28. Juli 2003, 16:19
Wohnort: /dev/reality

Ja logisch brauchst du den FB-Client für den Zugriff.

Ob es reicht, einfach ein paar Dateien irgendwo hinzukopieren?
Da sag ich mal nichts zu.

Den Client installieren geht ganz einfach
-Firebird Installer Starten und die Server-Komponenten deaktivieren, alles andere kannst du so lassen.

mfg, querdenker
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Habe die Datei `fbclient.dll` jetzt einfach in das Verzeichnis kopiert, wo das Python-Skript liegt. Es geht einen Schritt weiter:
Traceback (most recent call last):
[...]
ImportError: kinterbasdb uses the mx.DateTime module (from the "eGenix mx Base P
ackage") by default for date/time/timestamp representation, but you do not have
this package installed.
You can either download the eGenix mx Base Package from
http://www.egenix.com/files/python/eGen ... oad-mxBASE
or tell kinterbasdb to use the Python standard library datetime module instead,
as explained at
http://kinterbasdb.sourceforge.net/dist ... atetime_re
quired
Laut Dokumentation soll man den Import-Befehl wie folgt ändern, wenn man keine Abwärtskompatibilität benötigt und auf das eGenix mx Base Package verzichten kann:

Code: Alles auswählen

# import and don't use `eGenix mx Base Package` with mx.DateTime
import kinterbasdb; kinterbasdb.init(type_conv=200)
Hab ich gemacht mit folgendem Ergebnis:
Traceback (most recent call last):
File "test.py", line 15, in ?
pic.write(dump[0])
TypeError: argument 1 must be string or read-only buffer, not tuple
Aha, ein print type(dump[0]) bringt <type 'tuple'>. Also hier der vollständig funktionierende Code für test.py:

Code: Alles auswählen

#-*- coding: iso-8859-1 -*-

# import and don't use `eGenix mx Base Package` with mx.DateTime
import kinterbasdb; kinterbasdb.init(type_conv=200)

pic=file('foo.jpg','wb')
con=kinterbasdb.connect(host='192.168.0.187', database='C:/Programme/Spam/Eggs.fdb', user='sysdba', password='masterkey')
cur=con.cursor()

stm='select IMAGE from MYTABLE where ID=1'
cur.execute(stm)
dump=cur.fetchall()
cur.close()
con.commit()
con.close()

pic.write(dump[0][0])
pic.close()
`foo.jpg` ist tatsächlich das Bild und ich kann es öffnen! :D Ich bin überglücklich!

Hier nochmal schnell die benötigten Schritte im Voraus:

So, kann man jetzt noch aus den Binärdaten auslesen, was das für ein Bildtyp ist, also den MIME-Typ?
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

querdenker hat geschrieben:Ob es reicht, einfach ein paar Dateien irgendwo hinzukopieren?
Da sag ich mal nichts zu.
Naja ich dachte bei DLLs ist das wie bei Python-Modulen. Zuerst wird im aktuellen Arbeitsverzeichnis gesucht und erst dann werden die globalen Pfade abgegrast. Es scheint auch so zu sein. Man muss halt immer nur die DLL im selben Verzeichnis wie die .py Datei haben. Bei einer QnD Standalone Applikation stört mich das nicht. 8)
querdenker
User
Beiträge: 424
Registriert: Montag 28. Juli 2003, 16:19
Wohnort: /dev/reality

Schön das es geklappt hat :D

Zum bestimmen des Dateityps : Müsste man eigentlich aus den header-Daten auslesen können.
Da kann ich dir allerdings nicht weiterhelfen.

mfg, querdenker
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Hier ein Beispiel:

Code: Alles auswählen

#-*- coding: iso-8859-1 -*-

import mimetypes

t=mimetypes.guess_type('foo.jpg')
print mimetypes.guess_extension(t[0])
Leider kommt dabei die Dateierweiterung ".jpe" raus und nicht wie gewöhnlich ".jpg". Hum.
Antworten