Python Sqlite3 将 BLOB 传递给用户定义的函数得到 None
Python Sqlite3 passing BLOB to user-defined function gives None
我试图将数据从 BLOB
列传递到用户定义的函数中,但它在该函数中显示为 None
。这只是一个怪癖,还是我做错了什么?
BLOB
数据是我使用 Python 2.7.12
放入 sqlite3
数据库的 jpeg。 table 的架构是 CREATE TABLE data (md5sum TEXT PRIMARY KEY, data BLOB);
import sqlite3
import hashlib
def p_data(x):
print [x]
return x
def p_md(x):
print [x]
return x
db=sqlite3.connect('tagged.db')
db.text_factory = str
db.create_function('P_DATA', 1, p_data)
db.create_function('P_MD', 1, p_md)
r = db.execute('SELECT P_MD(md5sum),P_DATA(data),data FROM data LIMIT 1')
for i in r:
print
# Don't want to print the thousands of bytes in i[-1]
print i[:1]
print hashlib.md5(i[-1]).hexdigest()
python test.py
[u'3040158ef2c323aaa63da499fc821d77']
[None]
('3040158ef2c323aaa63da499fc821d77', None)
3040158ef2c323aaa63da499fc821d77
编辑
我将我的主要程序归结为下面的脚本,以便更轻松地分享与我完全相同的内容 运行。测试二进制数据(图片)is my avatar image.
tagged.db
的简单初始化程序
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
PRAGMA writable_schema=ON;
INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)VALUES('table','files','files',0,'CREATE VIRTUAL TABLE "files" USING fts3(fname TEXT, orig_name TEXT, tags TEXT, md5sum TEXT)');
CREATE TABLE 'files_content'(docid INTEGER PRIMARY KEY, 'c0fname', 'c1orig_name', 'c2tags', 'c3md5sum');
CREATE TABLE 'files_segments'(blockid INTEGER PRIMARY KEY, block BLOB);
CREATE TABLE 'files_segdir'(level INTEGER,idx INTEGER,start_block INTEGER,leaves_end_block INTEGER,end_block INTEGER,root BLOB,PRIMARY KEY(level, idx));
CREATE TABLE data (md5sum TEXT PRIMARY KEY, data BLOB);
CREATE INDEX idx1 on data(md5sum);
PRAGMA writable_schema=OFF;
COMMIT;
test.py
的内容
import sqlite3
import hashlib
def p_data(x):
print 'inside p_data'
print '\t', [x]
return x
def p_md(x):
print 'inside p_md'
print '\t', [x]
return x
db=sqlite3.connect('tagged.db')
db.text_factory = str
db.create_function('P_DATA', 1, p_data)
db.create_function('P_MD', 1, p_md)
fname = '4f880f29b27d5b2c14399512b7155f96.png'
with open(fname, 'rb') as f:
data = f.read()
md = hashlib.md5(data).hexdigest()
db.execute('INSERT INTO files VALUES (?,?,?,?)', ('testname.png', fname, 'testtag', md))
db.execute('INSERT INTO data VALUES (?,?)', (md, data))
# Don't commit so tagged.db will be empty each time test.py is started
r = db.execute('SELECT P_MD(md5sum),P_DATA(data),data FROM data LIMIT 1')
for i in r:
print
print i[:1]
print hashlib.md5(i[-1]).hexdigest()
print
print 'Testing "SELECT typeof(data) FROM data LIMIT 1"'
r = db.execute('SELECT typeof(data) FROM data LIMIT 1')
print r.fetchone()
print
print 'Testing "SELECT p_data("Have some text")'
r = db.execute("SELECT p_data('Have some text')")
v = r.fetchone()
print v
print [str(v[0])]
print
print 'Testing "SELECT p_data(x\'112233\')"'
r = db.execute("SELECT p_data(x'112233')")
v = r.fetchone()
print v
运行 python test.py
inside p_md
[u'c337ae2a8ebd84b7e50240d875b2729e']
inside p_data
[None]
('c337ae2a8ebd84b7e50240d875b2729e',)
c337ae2a8ebd84b7e50240d875b2729e
Testing "SELECT typeof(data) FROM data LIMIT 1"
('text',)
Testing "SELECT p_data("Have some text")
inside p_data
[u'Have some text']
('Have some text',)
['Have some text']
Testing "SELECT p_data(x'112233')"
inside p_data
[<read-write buffer ptr 0x7f31080cad18, size 3 at 0x7f31080cacd8>]
(<read-write buffer ptr 0x7f31080cad18, size 3 at 0x7f31080cacd8>,)
['\x11"3']
在 test.py
中,您会发现 type(data)
是 str
,这意味着它是作为文本插入的,当您读回它时可能会对编码感到困惑。
解决办法是插入一个sqlite3.Binary
代替:
db.execute('INSERT INTO data VALUES (?,?)', (md, sqlite3.Binary(data)))
我试图将数据从 BLOB
列传递到用户定义的函数中,但它在该函数中显示为 None
。这只是一个怪癖,还是我做错了什么?
BLOB
数据是我使用 Python 2.7.12
放入 sqlite3
数据库的 jpeg。 table 的架构是 CREATE TABLE data (md5sum TEXT PRIMARY KEY, data BLOB);
import sqlite3
import hashlib
def p_data(x):
print [x]
return x
def p_md(x):
print [x]
return x
db=sqlite3.connect('tagged.db')
db.text_factory = str
db.create_function('P_DATA', 1, p_data)
db.create_function('P_MD', 1, p_md)
r = db.execute('SELECT P_MD(md5sum),P_DATA(data),data FROM data LIMIT 1')
for i in r:
print
# Don't want to print the thousands of bytes in i[-1]
print i[:1]
print hashlib.md5(i[-1]).hexdigest()
python test.py
[u'3040158ef2c323aaa63da499fc821d77']
[None]
('3040158ef2c323aaa63da499fc821d77', None)
3040158ef2c323aaa63da499fc821d77
编辑
我将我的主要程序归结为下面的脚本,以便更轻松地分享与我完全相同的内容 运行。测试二进制数据(图片)is my avatar image.
tagged.db
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
PRAGMA writable_schema=ON;
INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)VALUES('table','files','files',0,'CREATE VIRTUAL TABLE "files" USING fts3(fname TEXT, orig_name TEXT, tags TEXT, md5sum TEXT)');
CREATE TABLE 'files_content'(docid INTEGER PRIMARY KEY, 'c0fname', 'c1orig_name', 'c2tags', 'c3md5sum');
CREATE TABLE 'files_segments'(blockid INTEGER PRIMARY KEY, block BLOB);
CREATE TABLE 'files_segdir'(level INTEGER,idx INTEGER,start_block INTEGER,leaves_end_block INTEGER,end_block INTEGER,root BLOB,PRIMARY KEY(level, idx));
CREATE TABLE data (md5sum TEXT PRIMARY KEY, data BLOB);
CREATE INDEX idx1 on data(md5sum);
PRAGMA writable_schema=OFF;
COMMIT;
test.py
import sqlite3
import hashlib
def p_data(x):
print 'inside p_data'
print '\t', [x]
return x
def p_md(x):
print 'inside p_md'
print '\t', [x]
return x
db=sqlite3.connect('tagged.db')
db.text_factory = str
db.create_function('P_DATA', 1, p_data)
db.create_function('P_MD', 1, p_md)
fname = '4f880f29b27d5b2c14399512b7155f96.png'
with open(fname, 'rb') as f:
data = f.read()
md = hashlib.md5(data).hexdigest()
db.execute('INSERT INTO files VALUES (?,?,?,?)', ('testname.png', fname, 'testtag', md))
db.execute('INSERT INTO data VALUES (?,?)', (md, data))
# Don't commit so tagged.db will be empty each time test.py is started
r = db.execute('SELECT P_MD(md5sum),P_DATA(data),data FROM data LIMIT 1')
for i in r:
print
print i[:1]
print hashlib.md5(i[-1]).hexdigest()
print
print 'Testing "SELECT typeof(data) FROM data LIMIT 1"'
r = db.execute('SELECT typeof(data) FROM data LIMIT 1')
print r.fetchone()
print
print 'Testing "SELECT p_data("Have some text")'
r = db.execute("SELECT p_data('Have some text')")
v = r.fetchone()
print v
print [str(v[0])]
print
print 'Testing "SELECT p_data(x\'112233\')"'
r = db.execute("SELECT p_data(x'112233')")
v = r.fetchone()
print v
运行 python test.py
inside p_md
[u'c337ae2a8ebd84b7e50240d875b2729e']
inside p_data
[None]
('c337ae2a8ebd84b7e50240d875b2729e',)
c337ae2a8ebd84b7e50240d875b2729e
Testing "SELECT typeof(data) FROM data LIMIT 1"
('text',)
Testing "SELECT p_data("Have some text")
inside p_data
[u'Have some text']
('Have some text',)
['Have some text']
Testing "SELECT p_data(x'112233')"
inside p_data
[<read-write buffer ptr 0x7f31080cad18, size 3 at 0x7f31080cacd8>]
(<read-write buffer ptr 0x7f31080cad18, size 3 at 0x7f31080cacd8>,)
['\x11"3']
在 test.py
中,您会发现 type(data)
是 str
,这意味着它是作为文本插入的,当您读回它时可能会对编码感到困惑。
解决办法是插入一个sqlite3.Binary
代替:
db.execute('INSERT INTO data VALUES (?,?)', (md, sqlite3.Binary(data)))