我正在尝试编写一个简单的Python脚本,将.odt文档插入到SQLite数据库中.这是我到目前为止所做的,但它似乎不起作用:
f=open('Loremipsum.odt', 'rb') k=f.read() f.close() cursor.execute="INSERT INTO notes (note) VALUES ('%s')" %(sqlite.Binary(k)) cursor.close() conn.close()
我没有收到任何错误消息,但据我所知,记录未插入.我究竟做错了什么?另外,如何将存储的文档提取回来?谢谢!
不知道sqlite.Binary
你正在使用什么,但是,无论如何,这是一个有效的例子:
import sqlite3 # let's just make an arbitrary binary file... with open('/tmp/abin', 'wb') as f: f.write(''.join(chr(i) for i in range(55))) # ...and read it back into a blob with open('/tmp/abin', 'rb') as f: ablob = f.read() # OK, now for the DB part: we make it...: db = sqlite3.connect('/tmp/thedb') db.execute('CREATE TABLE t (thebin BLOB)') db.execute('INSERT INTO t VALUES(?)', [buffer(ablob)]) db.commit() db.close() # ...and read it back: db = sqlite3.connect('/tmp/thedb') row = db.execute('SELECT * FROM t').fetchone() print repr(str(row[0]))
当使用Python 2.6运行时,此代码按预期和期望显示:'\ x00\x01\x02\x03\x04\x05\x06\x07\x08\t \n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!"#$%&\'()*+, - ./ 0123456'
注意需要使用buffer
插入blob,并将str
其作为字符串读回(因为它也使用buffer
类型作为结果) - 如果你只是要将它写入磁盘,则不需要后一段(因为write
文件的方法接受缓冲对象就像接受字符串一样).
给定示例存在多个问题.我会逐一解决.
没有错误检查.我们需要使用try/except/finally构造或使用with关键字.
Python方法与C#属性不同.您没有运行该execute()
方法,您正在为对象分配一些字符串.(在Python中,方法也是对象.)
非常重要的是您的代码受SQL注入攻击.我们永远不应该使用Python字符串操作构建SQL语句.我们应该总是使用占位符.
这个例子不完整.这导致了一个棘手的问题.假设有一个CREATE TABLE
语句,那么将创建一个新的隐式事务.并且commit()
必须发出声明以将数据保存到数据库文件中.在SQLite中,除了SELECT
启动隐式事务之外的任何语句.(某些数据库,如MySQL,默认情况下处于自动提交模式.对于SQLite,情况并非如此.)
这是一个正确的工作示例,它将LibreOffice文档写入SQLite数据库的Docs表:
#!/usr/bin/python # -*- coding: utf-8 -*- import sqlite3 as lite fl = open('book.odt', 'rb') with fl: data = fl.read() con = lite.connect('test.db') with con: cur = con.cursor() cur.execute("CREATE TABLE IF NOT EXISTS Docs(Data BLOB)") sql = "INSERT INTO Docs(Data) VALUES (?)" cur.execute(sql, (lite.Binary(data), ))
book.odt文件位于当前工作目录中.我们没有手动调用commit()方法,因为这是由幕后的with关键字处理的.
问题:
您没有显示您运行的完整代码.你不应该让回答者猜测是什么样的sqlite.Binary(k)
.
基本问题:您没有提交您的交易.conn.commit()
之前使用conn.close()
.