如何使用 python 在 sqlite 数据库中存储 jpg
how to store a jpg in an sqlite database with python
我已经尝试了很多天来找到解决这个问题的方法。我需要为 sqlite 数据库中的每条记录写一个小的 jpg 图像。
最后我设法插入了文件,但从它在数据库中写入的大小来看是原始文件而不是(压缩的)jpg。
我使用的代码是:
imgobj = Image.open('./fotocopies/checks/633.jpg')
con = sqlite3.connect("pybook.db")
cur = con.cursor()
cur.execute("UPDATE data_fotocopies SET fotocopy=? WHERE refid=633 and reftype=0", [ buffer(imgobj.tobytes()) ] )
如果我尝试 open
无法将文件插入数据库,则以下代码:
imgobj = open('./fotocopies/checks/632.jpg')
con = sqlite3.connect("pybook.db")
cur = con.cursor()
cur.execute("UPDATE data_fotocopies SET fotocopy=? WHERE refid=632 and reftype=0", [sqlite3.Binary(imgobj)] )
给出以下错误:
cur.execute("UPDATE data_fotocopies SET fotocopy=? WHERE refid=632 and reftype=0", [sqlite3.Binary(imgobj)] )
TypeError: buffer object expected
不幸的是,Whosebug 中没有以前的答案涵盖我,因为我已经尝试了所有这些。此外,所有存储检索都必须通过 gtk3 接口完成,我怀疑这将意味着另一个(系列)问题,即如何设置现有图像以从数据库响应等中获取其数据。
有人可以帮忙吗?
存储和检索 BLOB
import sqlite3
import os.path
from os import listdir, getcwd
from IPython.core.display import Image
def get_picture_list(rel_path):
abs_path = os.path.join(os.getcwd(),rel_path)
print 'abs_path =', abs_path
dir_files = os.listdir(abs_path)
return dir_files
def create_or_open_db(db_file):
db_is_new = not os.path.exists(db_file)
conn = sqlite3.connect(db_file)
if db_is_new:
print 'Creating schema'
sql = '''create table if not exists PICTURES(
ID INTEGER PRIMARY KEY AUTOINCREMENT,
PICTURE BLOB,
TYPE TEXT,
FILE_NAME TEXT);'''
conn.execute(sql) # shortcut for conn.cursor().execute(sql)
else:
print 'Schema exists\n'
return conn
def insert_picture(conn, picture_file):
with open(picture_file, 'rb') as input_file:
ablob = input_file.read()
base=os.path.basename(picture_file)
afile, ext = os.path.splitext(base)
sql = '''INSERT INTO PICTURES
(PICTURE, TYPE, FILE_NAME)
VALUES(?, ?, ?);'''
conn.execute(sql,[sqlite3.Binary(ablob), ext, afile])
conn.commit()
def extract_picture(cursor, picture_id):
sql = "SELECT PICTURE, TYPE, FILE_NAME FROM PICTURES WHERE id = :id"
param = {'id': picture_id}
cursor.execute(sql, param)
ablob, ext, afile = cursor.fetchone()
filename = afile + ext
with open(filename, 'wb') as output_file:
output_file.write(ablob)
return filename
conn = create_or_open_db('picture_db.sqlite')
picture_file = "./pictures/Chrysanthemum50.jpg"
insert_picture(conn, picture_file)
conn.close()
conn = create_or_open_db('picture_db.sqlite')
cur = conn.cursor()
filename = extract_picture(cur, 1)
cur.close()
conn.close()
Image(filename='./'+filename)
由于 Andrej Kesely 的评论,我终于让它工作了。工作解决方案是
imgobj = base64.b64encode(open('./fotocopies/checks/624.jpg').read())
con = sqlite3.connect("pybook.db")
cur = con.cursor()
qf="UPDATE data_fotocopies SET fotocopy='%s' WHERE refid=%d AND reftype=0"%(lite.Binary(fotocopy_blob),id)
cur.execute(qf) #yes, it is dangerous for injection`
从数据库中检索图像的操作如下:
qf="SELECT fotocopy FROM data_fotocopies WHERE refid=%d and reftype=0"%self.check_id
self.cur.execute(qf)
try:
fd=base64.b64decode(self.cur.fetchall()[0][0])
byting = GLib.Bytes(fd)
self.fotocopy = Gio.MemoryInputStream.new_from_bytes(byting)
...
self.fotocopy_ent=self.builder.get_object("fotocopy") # as it is made in glade
pixbuf = GdkPixbuf.Pixbuf.new_from_stream(self.fotocopy,None) #finally the pixbuf although
#it produces errors if I have
#no stream/image to "feed" it.
self.fotocopy_ent.set_from_pixbuf(pixbuf)
仍然无法弄清楚为什么我找到的所有其他解决方案都不起作用。我使用 Python 2.7.6 ang gtk3,但我使用的是这个。
谢谢大家的帮助。
我已经尝试了很多天来找到解决这个问题的方法。我需要为 sqlite 数据库中的每条记录写一个小的 jpg 图像。 最后我设法插入了文件,但从它在数据库中写入的大小来看是原始文件而不是(压缩的)jpg。 我使用的代码是:
imgobj = Image.open('./fotocopies/checks/633.jpg')
con = sqlite3.connect("pybook.db")
cur = con.cursor()
cur.execute("UPDATE data_fotocopies SET fotocopy=? WHERE refid=633 and reftype=0", [ buffer(imgobj.tobytes()) ] )
如果我尝试 open
无法将文件插入数据库,则以下代码:
imgobj = open('./fotocopies/checks/632.jpg')
con = sqlite3.connect("pybook.db")
cur = con.cursor()
cur.execute("UPDATE data_fotocopies SET fotocopy=? WHERE refid=632 and reftype=0", [sqlite3.Binary(imgobj)] )
给出以下错误:
cur.execute("UPDATE data_fotocopies SET fotocopy=? WHERE refid=632 and reftype=0", [sqlite3.Binary(imgobj)] )
TypeError: buffer object expected
不幸的是,Whosebug 中没有以前的答案涵盖我,因为我已经尝试了所有这些。此外,所有存储检索都必须通过 gtk3 接口完成,我怀疑这将意味着另一个(系列)问题,即如何设置现有图像以从数据库响应等中获取其数据。 有人可以帮忙吗?
存储和检索 BLOB
import sqlite3
import os.path
from os import listdir, getcwd
from IPython.core.display import Image
def get_picture_list(rel_path):
abs_path = os.path.join(os.getcwd(),rel_path)
print 'abs_path =', abs_path
dir_files = os.listdir(abs_path)
return dir_files
def create_or_open_db(db_file):
db_is_new = not os.path.exists(db_file)
conn = sqlite3.connect(db_file)
if db_is_new:
print 'Creating schema'
sql = '''create table if not exists PICTURES(
ID INTEGER PRIMARY KEY AUTOINCREMENT,
PICTURE BLOB,
TYPE TEXT,
FILE_NAME TEXT);'''
conn.execute(sql) # shortcut for conn.cursor().execute(sql)
else:
print 'Schema exists\n'
return conn
def insert_picture(conn, picture_file):
with open(picture_file, 'rb') as input_file:
ablob = input_file.read()
base=os.path.basename(picture_file)
afile, ext = os.path.splitext(base)
sql = '''INSERT INTO PICTURES
(PICTURE, TYPE, FILE_NAME)
VALUES(?, ?, ?);'''
conn.execute(sql,[sqlite3.Binary(ablob), ext, afile])
conn.commit()
def extract_picture(cursor, picture_id):
sql = "SELECT PICTURE, TYPE, FILE_NAME FROM PICTURES WHERE id = :id"
param = {'id': picture_id}
cursor.execute(sql, param)
ablob, ext, afile = cursor.fetchone()
filename = afile + ext
with open(filename, 'wb') as output_file:
output_file.write(ablob)
return filename
conn = create_or_open_db('picture_db.sqlite')
picture_file = "./pictures/Chrysanthemum50.jpg"
insert_picture(conn, picture_file)
conn.close()
conn = create_or_open_db('picture_db.sqlite')
cur = conn.cursor()
filename = extract_picture(cur, 1)
cur.close()
conn.close()
Image(filename='./'+filename)
由于 Andrej Kesely 的评论,我终于让它工作了。工作解决方案是
imgobj = base64.b64encode(open('./fotocopies/checks/624.jpg').read())
con = sqlite3.connect("pybook.db")
cur = con.cursor()
qf="UPDATE data_fotocopies SET fotocopy='%s' WHERE refid=%d AND reftype=0"%(lite.Binary(fotocopy_blob),id)
cur.execute(qf) #yes, it is dangerous for injection`
从数据库中检索图像的操作如下:
qf="SELECT fotocopy FROM data_fotocopies WHERE refid=%d and reftype=0"%self.check_id
self.cur.execute(qf)
try:
fd=base64.b64decode(self.cur.fetchall()[0][0])
byting = GLib.Bytes(fd)
self.fotocopy = Gio.MemoryInputStream.new_from_bytes(byting)
...
self.fotocopy_ent=self.builder.get_object("fotocopy") # as it is made in glade
pixbuf = GdkPixbuf.Pixbuf.new_from_stream(self.fotocopy,None) #finally the pixbuf although
#it produces errors if I have
#no stream/image to "feed" it.
self.fotocopy_ent.set_from_pixbuf(pixbuf)
仍然无法弄清楚为什么我找到的所有其他解决方案都不起作用。我使用 Python 2.7.6 ang gtk3,但我使用的是这个。
谢谢大家的帮助。