如何在Python中调用SQLite时通过名称引用列?

问题描述:

我有一些代码,我一直在使用查询MySQL,我希望可以用它与SQLite。我真正的希望是,这不会对代码做太多改动。不幸的是,下面的代码不使用SQLite工作:如何在Python中调用SQLite时通过名称引用列?

cursor.execute(query) 

rows = cursor.fetchall() 

data = [] 
for row in rows 
    data.append(row["column_name"]) 

这提供了以下错误:

TypeError: tuple indices must be integers 

而如果我改变参考使用列号,它工作正常:

data.append(row[1]) 

我可以执行查询吗?我可以通过他们的名字引用列吗?

我不知道这是否是最好的方法,但在这里就是我通常做检索记录使用DB-API 2兼容的模块设置:

cursor.execute("""SELECT foo, bar, baz, quux FROM table WHERE id = %s;""", 
        (interesting_record_id,)) 

for foo, bar, baz, quux in cursor.fetchall(): 
    frobnicate(foo + bar, baz * quux) 

查询格式化方法之一DB-API标准,但恰巧是Psycopg2的首选方法;其他DB-API适配器可能会提出一个不同的约定,这将是很好的。

写这样的查询,其中隐式元组解包用于处理结果集,对于我来说通常比​​试图担心将Python变量名匹配到SQL列名称更为有效(我通常只使用它来放置前缀,然后只有当我使用列名称的子集,以使前缀无助于澄清事情时),并且很多比记住数字列ID更好。

此样式还可以帮助您避免SELECT * FROM table...,这只是最简单的表和查询之外的任何维护灾难。

所以,不完全是你要求的答案,但可能有启发性。

+0

其实,这是完美的!谢谢。 – Ben 2009-02-23 09:13:06

+0

对不起:应该仔细检查一下。它不太有效。使用SQLite,foo最终变成类似(123)的形式,而使用MySQL时变成('foo':123) – Ben 2009-02-23 09:27:15

+0

像这样得到的结果让我怀疑你的MySQL模块是否符合DB-API 2.0 ......如果它是不是,试图替换不同的数据库模块会变得很难看。你使用哪个MySQL模块? – kquinn 2009-02-23 09:28:57

要按名称访问列,请使用Connection实例的row_factory属性。它可以让你设置一个函数,其参数为cursorrow,并返回任何你想要的。有一些内置的pysqlite,即sqlite3.Row,它可以满足您的要求。

SQLite的API支持cursor.description中,所以你可以很容易地做这样的

headers = {} 
for record in cursor.fetchall(): 
    if not headers: 
     headers = dict((desc[0], idx) for idx,desc in cursor.description)) 
    data.append(record[headers['column_name']]) 

有点长篇大论,但能够完成任务。我注意到它们甚至在dict_factory下的factory.py文件中。

这可以通过 “连接” statment后添加一行来完成:

conn.row_factory = sqlite3.Row 

检查这里的文档: http://docs.python.org/library/sqlite3.html#accessing-columns-by-name-instead-of-by-index

kushal的回答this forum正常工作:

Use a DictCursor:

import MySQLdb.cursors 

. 
. 
. 
cursor = db.cursor (MySQLdb.cursors.DictCursor) 
cursor.execute (query) 
rows = cursor.fetchall() 

for row in rows: 
print row['employee_id'] 

请注意,列名称区分大小写。

自问题提出并回答之后的五年中,出现了一个非常简单的解决方案。任何新的代码都可以简单地将连接对象与行工厂一起打包。代码示例:

import sqlite3 

conn = sqlite3.connect('./someFile') 
conn.row_factory = sqlite3.Row  // Here's the magic! 

cursor = conn.execute("SELECT name, age FROM someTable") 
for row in cursor: 
    print(row['name']) 

这里有一些fine docs。请享用!