商店Gtk.文本缓冲区在SQL数据库中。编码问题

2024-06-16 12:42:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用python2/Gtk3/Glade编写一个笔记应用程序。你知道吗

注释存储在MySQL数据库中,并显示在TextView widget中。 我可以加载/存储/显示纯文本。但是,我希望能够添加图像到笔记页,并将它们存储在数据库.so数据必须串行化,我在弄清楚如何对进出数据库的串行数据进行编码/解码时遇到了一些困难。我收到unicode起始字节错误。如果我正在处理文件,我可以以二进制模式打开文件,但我是以字符串的形式存储在数据库中。我尝试过使用bytes()string.encode()[参见下面的示例代码]和其他一些方法将编码/解码为UTF-8和ASCII,但都不起作用。你知道吗

我使用此函数将图像添加到textview缓冲区:

def _AddImagetoNode(self,oWidget):
    filenm = None
    seliter = self.GetTreeSelection(self.treeview)
    filenm = self.FileOpenDiag("Select an Image To Insert.","Image","*.png,*.jpg,*.bmp")
    if filenm == None:
        return()

    #filenm =  "/home/drift/Pictures/a.png"
    buf = self.dataview.get_buffer()
    pixbuf = GdkPixbuf.Pixbuf.new_from_file(filenm)
    #pixbuf.scale_simple(dest_width, dest_height, gtk.gdk.INTERP_BILINEAR)
    buf.insert_pixbuf(buf.get_end_iter(), pixbuf) 
    self.dataview.set_buffer(buf)
    self.dataview.show()

这是存储textview缓冲区的函数:

def SaveDataView(self):
    global DataViewNode
    global DataViewIsImage

    if len(self.GetProjectName()) == 0:
        return()
    buf = self.dataview.get_buffer()

    format = buf.register_serialize_tagset()
    data2 = buf.serialize(buf, format, buf.get_start_iter(), buf.get_end_iter())

    #convert bytes(data) to string
    data = data2.decode(encoding='UTF-8') #<< i think my problem is here
    print("save b4 decode >>>>>>:%s"%data2)

    sql = "UPDATE " + self.GetProjectName() + " SET tDataPath=%s  WHERE tNodeID=%s"
    val = (data, DataViewNode)

    self.cursor.execute(sql,val)
    self.mariadb_connection.commit()

这是加载缓冲区的函数:

def UpdateDataView(self, nodeid):
    global DataViewNode
    #global DataViewIsFile
    DataViewNode=nodeid


    if self.GetProjectName() != None and DataViewNode != None:
        self.dataview.set_sensitive(True)
    else:
        self.dataview.set_sensitive(False)
        self.dataview.show()
        return()

    buf = self.dataview.get_buffer()
    buf.set_text('')
    enc = self.DbGetNodeData(nodeid)



    #convert string(enc) to bytes
    data = enc.encode(encoding='UTF-8')#<<< i think my problem is here
    print("update after decode >>>>>>>>>: %s"%data)
    ########### load
    format = buf.register_deserialize_tagset()
    buf.deserialize(buf, format, buf.get_end_iter(),data) 


    #buf.set_text(enc)
    self.dataview.set_buffer(buf)
    self.dataview.show()

我在用mysql.connector接口连接到mariadb。 这是sql连接字符串:

self.mariadb_connection = mariadb.connect(user='box', password='box', host='localhost', database='Boxer',charset='utf8')

这就是我得到的错误。你知道吗

Traceback (most recent call last): File "Boxer.py", line 402, in _TreeSelectionChanged self.SaveDataView() File "Boxer.py", line 334, in SaveDataView data = data2.decode(encoding='UTF-8') UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb4 in position 174: invalid start byte Traceback (most recent call last): File "Boxer.py", line 398, in _DataViewLostFocus self.SaveDataView() File "Boxer.py", line 334, in SaveDataView data = data2.decode(encoding='UTF-8') UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb4 in position 174: invalid start byte

有了这段代码,我可以在文本视图中添加/编辑纯文本,并成功地保存/加载它,但是一旦添加图像,我就会得到编码错误。任何帮助都将不胜感激。你知道吗


Tags: inselfdatagetbufferutfdecodeset
2条回答

下面是一个更完整的示例:

def example (self):

        #retrieve info from first textview
        buf = self.builder.get_object('textbuffer1')
        format = buf.register_serialize_tagset()
        data = buf.serialize(buf, format, buf.get_start_iter(), buf.get_end_iter())

        #run db update to prove it can be inserted into a database
        db = psycopg2.connect(database= 'silrep_restore3', host='192.168.0.101', 
                                        user='postgres', password = 'true', 
                                        port = '5432')
        c = db.cursor()
        c.execute("UPDATE products SET byt = %s WHERE id = 1", (psycopg2.Binary(data),))

        #append info to second treeview as a proof of concept
        c.execute("SELECT byt FROM products WHERE id = 1")
        data = c.fetchone()[0]

        buf = self.builder.get_object('textbuffer2')
        format = buf.register_deserialize_tagset()
        buf.deserialize(buf, format, buf.get_end_iter(), data)

既然您使用的是MySQL,我建议您阅读这篇article关于像您这样插入和检索数据的文章。你知道吗

以我为例,我用了一个“茶边”专栏。在MySQL中,这可能是BLOB或二进制类型。你知道吗

另外,很抱歉我的回答中没有完整的MySQL示例。我本来会发表评论的,但是评论的格式太差了。你知道吗

一切正常。多亏他们知道你的答案才是关键。对于其他对此有问题的人,我最终使用BLOB类型作为我处理的列的MySQL字段类型。我尝试了BINARY[it returned malformed serialize data]和VARBINARY[wouldn't even allow me to create the table],所以最终使用了LONGBLOB类型。 这是任何需要它的人的工作代码。你知道吗

def UpdateDataView(self, nodeid):
    global DataViewNode
    #global DataViewIsFile
    DataViewNode=nodeid


    if self.GetProjectName() != None and DataViewNode != None:
        self.dataview.set_sensitive(True)
    else:
        self.dataview.set_sensitive(False)
        self.dataview.show()
        return()

    buf = self.dataview.get_buffer()
    buf.set_text('')
    data = self.DbGetNodeData(nodeid)
    if data =='':
        return()


    format = buf.register_deserialize_tagset()
    buf.deserialize(buf, format, buf.get_end_iter(),data)       

    self.dataview.set_buffer(buf)
    self.dataview.show() 


def SaveDataView(self):
    global DataViewNode
    global DataViewIsImage

    if len(self.GetProjectName()) == 0:
        return()
    buf = self.dataview.get_buffer()
    enc = buf.get_text(buf.get_start_iter(),buf.get_end_iter(),False)
    self.AddData2Db(DataViewNode,enc)

    format = buf.register_serialize_tagset()
    data = buf.serialize(buf, format, buf.get_start_iter(), buf.get_end_iter())

    sql = "UPDATE " + self.GetProjectName() + " SET tDataPath=%s  WHERE tNodeID=%s"
    val = (data, DataViewNode)

    self.cursor.execute(sql,val)
    self.mariadb_connection.commit()

我用这个来创建表

sql = "CREATE TABLE %s (tParentNodeID TEXT,tNodeTxt TEXT,tNodeID TEXT,tDataPath LONGBLOB)" %pName
    self.cursor.execute(sql)
    self.mariadb_connection.commit()

相关问题 更多 >