如何在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...
,这只是最简单的表和查询之外的任何维护灾难。
所以,不完全是你要求的答案,但可能有启发性。
要按名称访问列,请使用Connection实例的row_factory
属性。它可以让你设置一个函数,其参数为cursor
和row
,并返回任何你想要的。有一些内置的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。请享用!
其实,这是完美的!谢谢。 – Ben 2009-02-23 09:13:06
对不起:应该仔细检查一下。它不太有效。使用SQLite,foo最终变成类似(123)的形式,而使用MySQL时变成('foo':123) – Ben 2009-02-23 09:27:15
像这样得到的结果让我怀疑你的MySQL模块是否符合DB-API 2.0 ......如果它是不是,试图替换不同的数据库模块会变得很难看。你使用哪个MySQL模块? – kquinn 2009-02-23 09:28:57