我正在使用 python2 / Gtk3 / Glade 开发一个笔记应用程序。
这些注释存储在MySQL数据库中,并显示在TextView widget
中。
我可以加载/存储/显示纯文本格式。但是我希望能够将图像添加到注释页面,并将其存储在数据库中。因此必须对数据进行序列化,并且在弄清楚如何对序列化的序列进行编码/解码时遇到了一些麻烦数据进出数据库。我收到Unicode起始字节错误。如果正在处理文件,则可以以二进制模式打开文件,但是我将其作为字符串存储在数据库中。我已经尝试过使用bytes()
和string.encode()
[参见下面的示例代码]和其他几种方法将 encoding / decoding 作为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')
这是我遇到的错误。
回溯(最近一次通话最后一次):文件“ Boxer.py”,第402行,在 _TreeSelectionChanged self.SaveDataView()文件SaveBoxView中的“ Boxer.py”文件,第334行 data = data2.decode(encoding ='UTF-8')UnicodeDecodeError:'utf-8'编解码器无法解码位置174的字节0xb4:无效的起始字节 追溯(最近一次通话):文件“ Boxer.py”,行398,在 _DataViewLostFocus self.SaveDataView()文件SaveBoxView中的“ Boxer.py”文件,第334行 data = data2.decode(encoding ='UTF-8')UnicodeDecodeError:'utf-8'编解码器无法解码位置174的字节0xb4:无效的起始字节
使用此代码,我可以在文本视图中添加/编辑纯文本并成功保存/加载,但是一旦添加图像,我就可以编码错误。任何帮助将不胜感激。
答案 0 :(得分:0)
这是一个更完整的示例:
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,以了解有关插入和检索数据的信息。
在我的示例中,我使用了一个bytea列。在MySQL中,这可能是BLOB或BINARY类型。
P.S。对不起,我的回答中没有完整的MySQL示例。我本来会发表评论,但是评论对于正确的格式是可悲的。
答案 1 :(得分:0)
得到它的效果。感谢theGtknerd,您的答案才是关键。对于任何对此有麻烦的人,我最终都将BLOB类型用于与该列一起工作的MySQL字段类型。我尝试使用BINARY [返回格式错误的序列化数据]和VARBINARY [甚至不允许我创建表],所以我最终使用了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()