如何序列pyodbc光标输出(从.fetchone
, .fetchmany
或.fetchall
)Python字典?
我使用bottlepy和需要返回字典,因此它可以返回它的JSON。
如何序列pyodbc光标输出(从.fetchone
, .fetchmany
或.fetchall
)Python字典?
我使用bottlepy和需要返回字典,因此它可以返回它的JSON。
如果你不知道提前列,使用cursor.description中建列名的列表,并压缩每一行产生词典列表。 示例假设连接和查询都建:
>>> cursor = connection.cursor().execute(sql)
>>> columns = [column[0] for column in cursor.description]
>>> print(columns)
['name', 'create_date']
>>> results = []
>>> for row in cursor.fetchall():
... results.append(dict(zip(columns, row)))
...
>>> print(results)
[{'create_date': datetime.datetime(2003, 4, 8, 9, 13, 36, 390000), 'name': u'master'},
{'create_date': datetime.datetime(2013, 1, 30, 12, 31, 40, 340000), 'name': u'tempdb'},
{'create_date': datetime.datetime(2003, 4, 8, 9, 13, 36, 390000), 'name': u'model'},
{'create_date': datetime.datetime(2010, 4, 2, 17, 35, 8, 970000), 'name': u'msdb'}]
使用@ Beargle与bottlepy结果,我能创造这个非常简洁的查询露出端点:
@route('/api/query/<query_str>')
def query(query_str):
cursor.execute(query_str)
return {'results':
[dict(zip([column[0] for column in cursor.description], row))
for row in cursor.fetchall()]}
下面是你也许可以使用缩写形式
>>> cursor.select("<your SQL here>")
>>> single_row = dict(zip(zip(*cursor.description)[0], cursor.fetchone()))
>>> multiple_rows = [dict(zip(zip(*cursor.description)[0], row)) for row in cursor.fetchall()]
当您添加*到一个列表中,您可能知道,你基本上除掉的名单,留下个人列表条目作为参数传递给您呼叫的功能。 通过使用拉链我们挑选1到n项和压缩在一起,他们就像在你的裤子拉链。
因此,通过使用
zip(*[(a,1,2),(b,1,2)])
# interpreted by python as zip((a,1,2),(b,1,2))
你得到
[('a', 'b'), (1, 1), (2, 2)]
由于描述是元组的元组,其中每个元组描述了报头和每列的数据类型,可以提取在第一元组的每个具有
>>> columns = zip(*cursor.description)[0]
相当于
>>> columns = [column[0] for column in cursor.description]
主要是要关闭@Torxed响应,我创建了一个完整的广义集功能找到架构和数据转换成字典:
def schema_dict(cursor):
cursor.execute("SELECT sys.objects.name, sys.columns.name FROM sys.objects INNER JOIN sys.columns ON sys.objects.object_id = sys.columns. object_id WHERE sys.objects.type = 'U';")
schema = {}
for it in cursor.fetchall():
if it[0] not in schema:
schema[it[0]]={'scheme':[]}
else:
schema[it[0]]['scheme'].append(it[1])
return schema
def populate_dict(cursor, schema):
for i in schema.keys():
cursor.execute("select * from {table};".format(table=i))
for row in cursor.fetchall():
colindex = 0
for col in schema[i]['scheme']:
if not 'data' in schema[i]:
schema[i]['data']=[]
schema[i]['data'].append(row[colindex])
colindex += 1
return schema
def database_to_dict():
cursor = connect()
schema = populate_dict(cursor, schema_dict(cursor))
随意走在这条所有代码高尔夫球场,以减少线路; 但在此期间,它的作品!
;)
我喜欢@bryan和@富堆栈的答案。 如果您正在使用PostgreSQL的工作,你正在使用psycopg2
你可以使用一些好吃的东西从psycopg2通过指定cursorfactory是一个以达到相同的DictCursor
从连接创建游标时,是这样的:
cur = conn.cursor( cursor_factory=psycopg2.extras.DictCursor )
所以现在你可以执行SQL查询,你会得到一本字典来获取你的结果,而不需要手工映射。
cur.execute( sql_query )
results = cur.fetchall()
for row in results:
print row['row_no']
请注意,您必须import psycopg2.extras
该工作。
我知道这个问题是旧的,但它帮助我弄清楚如何做我所需要的,这是比OP被要求略有不同,所以我想我会分享,以帮助其他人需要我需要的东西:如果要全面推广执行SQL选择查询的程序,但你需要使用索引号,而不是名称引用的结果,你可以这样做与列表,而不是一本字典的列表。 返回的数据的每一行中返回的列表作为字段(列)的值的列表表示。 列名可以作为返回列表的第一个条目,所以在解析调用程序返回的列表可以很容易和灵活。 通过这种方式,程序在做数据库调用并不需要知道,它的处理数据什么。 下面是这样一个例行:
def read_DB_Records(self, tablename, fieldlist, wherefield, wherevalue) -> list:
DBfile = 'C:/DATA/MyDatabase.accdb'
# this connection string is for Access 2007, 2010 or later .accdb files
conn = pyodbc.connect(r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ='+DBfile)
cursor = conn.cursor()
# Build the SQL Query string using the passed-in field list:
SQL = "SELECT "
for i in range(0, len(fieldlist)):
SQL = SQL + "[" + fieldlist[i] + "]"
if i < (len(fieldlist)-1):
SQL = SQL + ", "
SQL = SQL + " FROM " + tablename
# Support an optional WHERE clause:
if wherefield != "" and wherevalue != "" :
SQL = SQL + " WHERE [" + wherefield + "] = " + "'" + wherevalue + "';"
results = [] # Create the results list object
cursor.execute(SQL) # Execute the Query
# (Optional) Get a list of the column names returned from the query:
columns = [column[0] for column in cursor.description]
results.append(columns) # append the column names to the return list
# Now add each row as a list of column data to the results list
for row in cursor.fetchall(): # iterate over the cursor
results.append(list(row)) # add the row as a list to the list of lists
cursor.close() # close the cursor
conn.close() # close the DB connection
return results # return the list of lists
假设你知道你的列名! 此外,这里有三个不同的解决方案,
你可能想看看在最后一个!
colnames = ['city', 'area', 'street']
data = {}
counter = 0
for row in x.fetchall():
if not counter in data:
data[counter] = {}
colcounter = 0
for colname in colnames:
data[counter][colname] = row[colcounter]
colcounter += 1
counter += 1
这是一个索引的版本,而不是最漂亮的解决方案,但它会奏效。 另一个办法是索引列名与含有中的行号顺序数据中的每个项中的一个列表的字典键。 通过做:
colnames = ['city', 'area', 'street']
data = {}
for row in x.fetchall():
colindex = 0
for col in colnames:
if not col in data:
data[col] = []
data[col].append(row[colindex])
colindex += 1
写这篇,我了解,这样for col in colnames
可以被替代for colindex in range(0, len())
但你的想法。 当未获取所有数据后面的例子中寿将是有益的,但在一次一行,例如:
def fetchone_dict(stuff):
colnames = ['city', 'area', 'street']
data = {}
for colindex in range(0, colnames):
data[colnames[colindex]] = stuff[colindex]
return data
row = x.fetchone()
print fetchone_dict(row)['city']
获取表名(我想..感谢美孚栈):
从下面beargle 更直接的解决方案 !
cursor.execute("SELECT sys.objects.name, sys.columns.name FROM sys.objects INNER JOIN sys.columns ON sys.objects.object_id = sys.columns. object_id WHERE sys.objects.type = 'U';")
schema = {}
for it in cursor.fetchall():
if it[0] in schema:
schema[it[0]].append(it[1])
else:
schema[it[0]] = [it[1]]
对于将光标不可用的情况 - 例如,当行已经被一些函数调用或内部方法返回,您仍然可以通过row.cursor_description创建一个字典表示
def row_to_dict(row):
return dict(zip([t[0] for t in row.cursor_description], row))