Python Sqlite3 将 BLOB 传递给用户定义的函数给出 None

标签 python sqlite user-defined-functions

我试图将数据从 BLOB 列传递到用户定义的函数中,但它在该函数中显示为 None。这只是一个怪癖,还是我做错了什么?

BLOB 数据是我使用 Python 2.7.12 放入 sqlite3 数据库中的 jpeg。该表的架构为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)))

关于Python Sqlite3 将 BLOB 传递给用户定义的函数给出 None,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47481047/

相关文章:

SQL Server 2005 表值函数奇怪的性能

python - PySpark 中 pandas_udf 的隐式模式?

python - 无法使用 SQLAlchemy/Flask-SQLAlchemy 删除行

python - Spark DF pivot error : Method pivot([class java. lang.String, class java.lang.String]) 不存在

iphone - 在 SQLite 数据库的 uiwebview 中显示 HTML 文件?

ruby-on-rails - 从具有 500k 条记录的模型中快速对记录进行排序

python - 覆盆子上的 Kivy : Cursor is outside of window

python - 如何使用Python的re模块将 '1:2:3'归一化为 '01:02:03'?

java - 如何在android中的数据库上更改数据时得到通知?

vba - 替代命令 (ActiveSheet)