使用sqlite3.Row按名称索引结果时行为不一致
在我的Python应用程序中,我一直使用sqlite3.Row作为行工厂,这样可以通过名称来索引结果,一直没有问题。最近,我把应用程序迁移到了一个新服务器(代码没有改动),结果发现这种索引方法在新服务器上出现了意外的失败,且是在一个特定的条件下。我找不到任何解释。
这个问题似乎是在新服务器上,当我在选择查询中使用了DISTINCT
关键字时发生的:
import sqlite3
conn = sqlite3.connect(':memory:')
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('create table test ([name] text)')
c.execute("insert into test values ('testing')")
conn.commit()
c.execute('select [name] from test')
row = c.fetchone()
print row['name'] # works fine on both machines
c.execute('select distinct [name] from test') # add distinct keyword
row = c.fetchone()
print row['name'] # fails on new server (no item with that key)
正如你所看到的,我可以通过使用内存数据库来隔离这个问题,所以这个问题和我现有的数据没有关系。两台机器都是基于Debian的(旧的:Ubuntu 8.10,新的是Debian 5.0.3),而且两台机器都在运行Python 2.5.2。我相信sqlite3模块是Python安装的核心部分,所以我不知道为什么在Python版本相同的情况下会出现这种微妙的故障。
有没有人有任何想法,或者见过类似的情况?
谢谢,
Chris
2 个回答
0
我遇到了一个不同但类似的问题,搜索“indexerror no item with that key”让我找到了这个问题。在我的情况下,问题出在不同版本的sqlite在使用row_factory = sqlite3.Row模式时,对行的键名处理方式不同。在sqlite 3.24.0版本中,像这样的查询:
select table.col
from table
...会在行字典中创建一个像col
这样的键。但在旧版本中,似乎使用的是带有表名的键,比如table.col
。提供一个明确的别名或者不使用表名来限定列名可以作为解决方法。例如:
select table.col as "col"
from table
或者:
select col
from table
1
试着加上这一行:
print row.keys()
而不是用“print row['name']”,这样你就能看到在第二种情况下,第一列的实际名称是什么(可能是因为用了“DISTINCT”这个关键词而改变了)。
另外,你也可以在这种情况下用 row[0],但这可能不是你想要的结果。:)