Fetch Blob Data

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
fanus
User
Beiträge: 46
Registriert: Dienstag 13. November 2007, 09:53

Hallo liebe Leute,

mal wieder eine newbieFrage: kann mir bitte jemand sagen wie man, den in der MySQL DatenBank gespeicherten File, plotten/zeigen lassen??
hier ist ein kleines beispiel: (interessant ist Zeile 76 :))

Code: Alles auswählen

import wx
import os
import MySQLdb 

""" 
CREATE TABLE save_blob ( 
  `f_id` int(10) unsigned NOT NULL auto_increment, 
  `f_blob` blob, 
  PRIMARY KEY  (`f_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
""" 
#------------------------------------------------------------------------          
class MyFrame(wx.Dialog): 
    def __init__(self, parent, title): 
        wx.Dialog.__init__(self, parent, -1, title, pos=(150, 150), size=(300, 350)) 
        
        self.ConnectToDB() 
        panel = wx.Panel(self, -1)
        
        self.BlobFile = ""
        self.result = "" 
        
        self.btn_Load = wx.Button(panel, -1, 'Load File') 
        self.btn_Load.Bind(wx.EVT_BUTTON, self.LoadFile) 
        self.btn_Save = wx.Button(panel, -1, 'Save File into MySQL-DB') 
        self.btn_Save.Bind(wx.EVT_BUTTON, self.SaveFile)
        self.btn_Read = wx.Button(panel, -1, 'Read File from MySQL-DB') 
        self.btn_Read.Bind(wx.EVT_BUTTON, self.FetchFile)
        
        btn_sizer = wx.BoxSizer(wx.HORIZONTAL) 
        btn_sizer.Add(self.btn_Load, -1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 15) 
        btn_sizer.Add(self.btn_Save, -1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 15)
        btn_sizer.Add(self.btn_Read, -1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 15)      
        
        main_sizer = wx.BoxSizer(wx.VERTICAL) 
        main_sizer.Add(btn_sizer, 0, wx.ALL|wx.ALIGN_CENTER|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 15) 
        
        panel.SetSizer(main_sizer) 
        main_sizer.Fit(self) 

        self.main_sizer = main_sizer 

        self.Bind(wx.EVT_CLOSE, self.OnClose) 

    def LoadFile(self, event): 
        wildcard = "(*.py) |*.py|"\
                    "(*.jpg) |*.jpg|"\
                    "All files (*.*)|*.*"
        dlg = wx.FileDialog(self, "Choose a File", os.getcwd(), "", wildcard, wx.OPEN) 
        if dlg.ShowModal() == wx.ID_OK: 
            
            filename = dlg.GetFilename() 
            dirname = dlg.GetDirectory()
            
            OpenFile = open(os.path.join(dirname, filename),'rb') 
            self.BlobFile = MySQLdb.Binary(OpenFile.read())
            OpenFile.close() 
        dlg.Destroy
        
        if event: 
            event.Skip() 

    def SaveFile(self, event):
        Cursor = self.Con.cursor() 
        sql = "INSERT INTO save_blob(f_blob) VALUES (%s)" 
        Cursor.execute(sql, self.BlobFile) 
        print "Blob wurde gespeichert!"
        self.Con.commit()
    
    
    def FetchFile(self, event):
        Cursor = self.Con.cursor() 
        sql = "SELECT f_blob FROM save_blob WHERE f_id = 1 " 
        Cursor.execute(sql)
        self.result = Cursor.fetchone()[0]
##      wie lasse ich hier mein result zeigen!!
        self.Con.commit() 
        
    def ConnectToDB(self): 
        self.Con = MySQLdb.Connect(host = "lokalhost",
                                 user = "user",
                                 passwd = "password",
                                 db = "db")        

    def OnClose(self, event):    
        self.Con.close() 
        self.Destroy() 
        
#------------------------------------------------------------------------ 
class MyApp(wx.App): 
    def OnInit(self): 
        dialog = MyFrame(None, 'BlobFile speichern') 
        if dialog.ShowModal() == wx.ID_OK: 
            print dialog.object.GetDate() 
        return True 
        
app = MyApp(0) 
app.MainLoop() 

LG,
fanus
:)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo fanus!

Du kannst aus diesem Stream ein Bitmap machen. Das geht über den Umweg als Image.

Code: Alles auswählen

img = wx.ImageFromStream(self.result, type = wx.BITMAP_TYPE_JPEG)
bmp = wx.BitmapFromImage(img)
Und dieses Bitmap kannst du dann z.B. in einem wx.StaticBitmap-Objekt anzeigen lassen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
fanus
User
Beiträge: 46
Registriert: Dienstag 13. November 2007, 09:53

erstmal frohes neus Jahr und danke gerold für die antwort!

ich möchte aber die in der DB gespeicherte Datei ganz einfach ausgeben können. bei PHP solte das so aussehen:
"
$uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
$extra = 'seite_b.php?file=';
header("Location: http://$host$uri/$extra" . $_POST['file']);
echo $host, $uri, $extra, $_POST['file'];
"

wie rufe ich das "DOWNLOAD FENSTER" mit Python?

danke für Eure Hilfe
LG,
fanus
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

fanus hat geschrieben:wie rufe ich das "DOWNLOAD FENSTER" mit Python?
Hallo fanus!

Das Download-Fenster ist ein Teil deines Browsers. Das hat nichts mit GUI-Programmierung mit wxPython zu tun.

Willst du, dass das Bild *in* deiner Anwendung angezeigt wird, dann gehe so vor wie ich es oben schon beschrieben habe. Mach aus dem Datenstream ein Image, wandle dieses Image in ein Bitmap um un zeige das Bitmap in einem wx.StaticBitmap-Widget an.

Willst du, dass das Bild in deinem bevorzugten Programm geöffnet wird, dann speichere den Datenstream in eine Datei mit der richtigen Endung (z.B. jpg oder gif) und übergebe (zumindest unter Windows) den Pfad zu dieser Datei an ``os.startfile``. Damit wird das Bild in der in Windows eingestellten Standardanwendung geöffnet.

Wenn du den Benutzer auswählen lassen möchtest, wohin der Datenstream gespeichert werden soll, dann kannst du diese Frage in einem ``wx.FileDialog`` stellen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
fanus
User
Beiträge: 46
Registriert: Dienstag 13. November 2007, 09:53

gerold hat geschrieben:
Willst du, dass das Bild in deinem bevorzugten Programm geöffnet wird, dann speichere den Datenstream in eine Datei mit der richtigen Endung (z.B. jpg oder gif) und übergebe (zumindest unter Windows) den Pfad zu dieser Datei an ``os.startfile``. Damit wird das Bild in der in Windows eingestellten Standardanwendung geöffnet.

Wenn du den Benutzer auswählen lassen möchtest, wohin der Datenstream gespeichert werden soll, dann kannst du diese Frage in einem ``wx.FileDialog`` stellen.
genau das! Gibts vllt im Forum ein Beispiel dazu?

Vielen Dank!

LG,
fanus
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

fanus hat geschrieben:Gibts vllt im Forum ein Beispiel dazu?
- Das Python-Forum hat eine Suchfunktion (TIPP)
- Die wxPython-Demo hat eine Suchfunktion (TIPP)
- Das http://wiki.wxpython.org/ hat eine Suchfunktion
- Im Index der Python-Hilfe http://docs.python.org/lib/genindex.html kann man mit dem Browser suchen. Damit findet man dann z.B. diese Seite: http://docs.python.org/lib/os-process.html#l2h-2760
- Die HTML-Help-Datei, die mit Python mit installiert wird, hat auch eine Suche eingebaut.
- In der WX-Widgets (C++) Dokumentation http://wxwidgets.org/manuals/stable/wx_contents.html kann man auch recht gut Suchen. Besonders in der "Alphabetical class reference" http://wxwidgets.org/manuals/stable/wx_classref.html

- http://www.python-forum.de/post-63467.html#63467
- http://www.python-forum.de/post-64646.html#64646
- http://wiki.wxpython.org/AnotherTutoria ... 8ea4ed8f85
- http://wxwidgets.org/manuals/stable/wx_ ... ialog.html

Und das Kapitel 6.3.1 in wxPython in Action erklärt wie man den Dateidialog verwendet.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
fanus
User
Beiträge: 46
Registriert: Dienstag 13. November 2007, 09:53

ich möchte aber das" Download-Fenster" benutzen? geht das nicht unter Python?

Code: Alles auswählen

        f = file(pdfdatei, "rb") 
        pdf = r.read() 
        RESPONSE.setHeader('content-type', 'application/pdf') 
        RESPONSE.setHeader('content-length', str(len(pdf))) 
        RESPONSE.setHeader('content-disposition', 'attachment; filename=seavas.pdf') 
        RESPONSE.write(pdf) 
        f.close() 
das haste ja schon mal gepostet.. funktioniert aber nicht!
LG,
fanus
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

fanus hat geschrieben:ich möchte aber das" Download-Fenster" benutzen? geht das nicht unter Python?

Code: Alles auswählen

        f = file(pdfdatei, "rb") 
        pdf = r.read() 
        RESPONSE.setHeader('content-type', 'application/pdf') 
        RESPONSE.setHeader('content-length', str(len(pdf))) 
        RESPONSE.setHeader('content-disposition', 'attachment; filename=seavas.pdf') 
        RESPONSE.write(pdf) 
        f.close() 
Hallo fanus!

Da du immer noch auf dem Holzweg bist, kläre ich dich mal auf.

Dieser Code den du oben siehst, wird von einem Webserver ausgeführt. Damit wird per HTTP ein Attachment an den Browser zurück gesendet. Das funktioniert aber nur, wenn der Browser die Daten vom Server anfordert. Der Server kann nicht einfach etwas an den Browser schicken, wenn es nicht von diesem angefordert wurde.

Das was du oben siehst ist Webprogrammierung. Diese lässt sich nicht mit der GUI-Programmierung (TkInter, wxPython, pyGTK,...) mischen. Mit diesen Frameworks erstellst du keine Webprogramme (die mit dem Browser bedient werden), sondern eigenständige Programme.

Und da das eigenständige Programme werden, kannst du nicht einfach irgend ein Bauteil (z.B. den Download-Dialog des Internet Explorers) eines anderen Programmes (z.B. dem Browser) in dein Programm einbauen. Das ist wie wenn ich in einem Hochhaus wohne und den Lift eines Nachbarhauses benutze um in meine Wohnung zu kommen, obwohl dieses Nachbarhaus 100 Meter entfernt ist. Das funktioniert einfach nicht.

Um dich zu verwirren: :wink: Du kannst den Browser indirekt mitbenutzen. Z.B. könntest du den Browser von deinem Programm aus starten und diesem über Kommandozeilenparameter anweisen, eine Internetseite zu öffnen. Dabei öffnet sich der Browser als eigenständiges Programm. Wenn dir der Internetserver statt einer HTML-Seite ein Attachment zurück gibt, dann wird der Browser auch diesen Download-Dialog anzeigen. Aber ich glaube nicht, dass du das willst. Denn so einen Download-Dialog kannst du dir in wxPython in wenigen Stunden selber machen. Und dann ist dieser in dein Programm integriert und kein Aufruf eines Fremdprogrammes.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
fanus
User
Beiträge: 46
Registriert: Dienstag 13. November 2007, 09:53

Hallo erstmal und danke gerold für die dolle Aufklärung.
gerold hat geschrieben:
Das ist wie wenn ich in einem Hochhaus wohne und den Lift eines Nachbarhauses benutze um in meine Wohnung zu kommen, obwohl dieses Nachbarhaus 100 Meter entfernt ist. Das funktioniert einfach nicht.
der Unterschied ist, dass Du die 100 Meter zw. den Häuser siehst. Ich aber nicht. Also nehme ich doch den Lift des Nachbarhauses.. fahre bis oben. Erst dann erkenne ich, dass es doch nicht möglich ist, in meine Wohnung zu kommen und fahre wieder nach unten.. dort nehme ich WIEDER DENSELBEN Lift.. ach was, ich bin eine schlechte Anfängerin.

so jetzt zurück...

mit einem FileDialog lasse ich die datei, die ich aus der DB geholt habe, lokal speichern. Die Größe stimmte mit der originalen datei aber der Inhalt nicht!(bei text dateien funktioniert alles prima, pdf jedoch nicht)

was muss ich noch beachten wenn ich die Datei zurückstelle?
Bitte Hilfe! und hier ist der Code:

http://paste.pocoo.org/show/20689/

EDIT by Gerold: Code ausgelagert.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo Fanus!

Probier mal statt

Code: Alles auswählen

f = open(self.filename, 'w+')

Code: Alles auswählen

f = open(self.filename, 'wb')
aus.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten