Python - 从SQLite3数据库中读取BLOB类型

4
这篇文章是关于之前这篇文章的延伸:Python - Converting Hex to INT/CHAR 我现在已经有了将存储在sqlite3数据库中的IP的十六进制值转换为可读和可用格式的解决方案。然而,直到现在,我一直在通过从sqlite3数据库查看器直接复制和粘贴来进行测试。
我一直试图使用脚本轮询数据库以查找该信息,但我发现它显然将blob数据存储到一个不立即人类可读的缓冲区中。
例如,IP 192.168.0.1 在字段ip下以blob类型存储为X'C0A80001'
由于我是从一个复制和粘贴的示例开始编写代码的,因此我构建了代码以从十六进制中剥离X'和'以进行转换。问题是我无法从数据库中获取该值(X'C0A80001' <- 这个值是我可以用数据库管理器查看的值)。 在搜索中,我发现http://eli.thegreenplace.net/2009/05/29/storing-blobs-in-a-sqlite-db-with-pythonpysqlite/,其中显示了一个读取Blob到sqlite数据库的示例,但它们的方法不起作用。它们会显示以下错误;
print row[0], str(row[1]).encode('hex')
IndexError: tuple index out of range

我对Python还很陌生,如果有人能提供指针或者代码示例来帮助我理解这个问题,我将不胜感激。

编辑: 糟糕,我忘记在上面的示例中粘贴代码了;

c = conn.cursor()
c.execute('select ip from item where name = ' + "\'" + host + "\'")
for row in c:
        print row[0], str(row[1]).encode('hex')

我可能对此的理解有误,导致我无法按照自己想要的方式读取它。
更新: 使用下面的答案,我修改了我的代码:
rows = c.execute('select ip from item where name= ' + "\"" + host + "\"") 
   for row in rows:
       print str(row[0]).encode("hex")

你在数据库中存储IP地址,但只有IPv4的。那IPv6呢? - glglgl
1个回答

4
检查链接后,最可能的解释是一个空行。在第29行,您设置了一个for循环来遍历查询结果。在Python中,这意味着您有一个列表:[item,item2,item3],每次循环时,您的row变量指向下一个项目。
在循环内部,您正在检查当前项目的内容。每个项目都是一个元组,据说至少有两个条目。但是,如果其中任何一个项目没有row [0]row [1]的条目,则会出现索引超出范围的异常。
您没有发布足够的代码来确定发生这种情况的原因,但为了使代码运行,我建议您这样做:
for row in cur.execute("select * from frames"):
    try:
        print row[0], str(row[1]).encode('hex') 
    except IndexError, e:
        print "IndexError: {0}".format(e)

即使其中一些查询结果不好,它也将在整个查询结果中继续。

编辑:我刚看到你的更新,你的问题是c没有保存查询的内容。c.execute('select ip from item where name = ' + "\'" + host + "\'")返回一个列表,但你忽略了它。

原始示例之所以有效,是因为你在for循环中获取了列表,因此它是一个匿名变量,仅限于循环上下文中。要修复你的代码:

c = conn.cursor()
rows = c.execute('select ip from item where name = ' + "\'" + host + "\'")
for row in rows:
        print row[0], str(row[1]).encode('hex')

谢谢!我太简单了。因此,IP字段是表中的第三个字段,所以我需要做的是使用您获取列表的修改访问row[2]。为了完整起见,我将编辑上面的问题以包括我的最终工作解决方案。再次感谢您。 - Draineh
1
@Draineh 没问题。我建议你阅读Python教程,或者至少浏览到第9章。这将解释各种Python结构,例如列表和循环。这不需要太长时间,而且可以避免很多麻烦。 - Spencer Rathbun
2
刚刚收到了《Python - Essential Reference》的邮寄,希望我能够学到一些不错的东西。 - Draineh
4
c.execute('select ip from item where name = ' + "\'" + host + "\'") 这种写法不太好,更好的写法是 c.execute('select ip from item where name = ?', host)。我不知道sqlite使用?还是MySQL使用的%s。请注意,这不会改变原来的意思。 - glglgl
@glglgl 谢谢,我曾经在某个地方读到过在Python中使用?与sqlite交互是一个好的实践,但是通过我的调试,我只是试图让基础工作正常运行 - 我会改变它的。 - Draineh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接