将pyodbc游标结果输出为python字典

将pyodbc游标结果输出为python字典,python,dictionary,cursor,pyodbc,pypyodbc,Python,Dictionary,Cursor,Pyodbc,Pypyodbc,如何将pyodbc游标输出(从.fetchone、.fetchmany或.fetchall)序列化为Python字典 我使用的是bottlepy,需要返回dict,以便它可以将其作为JSON返回。假设您知道自己的列名! 另外,这里有三种不同的解决方案, 你可能想看看最后一个 colnames = ['city', 'area', 'street'] data = {} counter = 0 for row in x.fetchall(): if not counter in data

如何将pyodbc游标输出(从
.fetchone
.fetchmany
.fetchall
)序列化为Python字典


我使用的是bottlepy,需要返回dict,以便它可以将其作为JSON返回。

假设您知道自己的列名! 另外,这里有三种不同的解决方案,
你可能想看看最后一个

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
这是一个索引版本,不是最漂亮的解决方案,但它会起作用。 另一种方法是将列名索引为dictionary键,每个键中都有一个列表,按照行号的顺序包含数据。通过这样做:

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
写这篇文章时,我知道对colnames中的col执行
可以替换为对范围(0,len())中的colindex执行
,但您明白了。 后面的示例tho在每次只提取一行数据而不提取所有数据时非常有用,例如:

对每行数据使用dict
获取表名(我想……多亏了Foo Stack):
一个更直接的解决方案来自下面的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]]

如果您事先不知道列,请使用构建列名列表,并使用每行生成字典列表。示例假设建立了连接和查询:

>>> 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'}]

我主要使用@Torxed response,创建了一组完整的通用函数,用于在字典中查找模式和数据:

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))
自由地去所有的代码高尔夫在此减少线;但同时,它也起作用了


)()

使用@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()]}
@route('/api/query/'))
def查询(查询字符串):
cursor.execute(query\u str)
返回{'results':
[dict(zip([column[0]表示游标中的列。说明],行))
对于游标中的行。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()]
你得到

[('a', 'b'), (1, 1), (2, 2)]
由于描述是一个包含元组的元组,其中每个元组描述每个列的标题和数据类型,因此可以使用

>>> columns = zip(*cursor.description)[0]
相当于

>>> columns = [column[0] for column in cursor.description]

我所需要的,与OP所要求的略有不同:
如果要完全概括执行SQL Select查询的例程,但需要通过索引号而不是名称引用结果,可以使用列表列表而不是字典来实现

返回数据的每一行在返回列表中表示为字段(列)值列表。
列名可以作为返回列表的第一个条目提供,因此在调用例程中解析返回列表非常简单和灵活。
这样,执行数据库调用的例程就不需要知道它正在处理的数据的任何信息。下面是这样一个例行公事:

    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
def read_DB_记录(self、tablename、fieldlist、wherefield、wherevalue)->列表:
DBfile='C:/DATA/MyDatabase.accdb'
#此连接字符串用于Access 2007、2010或更高版本的.accdb文件
conn=pyodbc.connect(r'Driver={Microsoft Access驱动程序(*.mdb,*.accdb)};DBQ='+DBfile)
游标=连接游标()
#使用传入的字段列表生成SQL查询字符串:
SQL=“选择”
对于范围内的i(0,len(字段列表)):
SQL=SQL+“[”+字段列表[i]+“]”
如果i<(len(字段列表)-1):
SQL=SQL+“,”
SQL=SQL+“来自”+表名
#支持可选的WHERE子句:
如果是wherefield!=”“那你的价值呢"" :
SQL=SQL+“其中[“+wherefield+”]=“+”“+wherevalue+”;”
结果=[]#创建结果列表对象
cursor.execute(SQL)#执行查询
#(可选)获取查询返回的列名列表:
columns=[column[0]表示游标中的列。说明]
results.append(columns)#将列名追加到返回列表中
#现在将每一行作为列数据列表添加到结果列表中
对于游标中的行。fetchall():#在游标上迭代
结果。追加(列表(行))#将行作为列表添加到列表列表中
cursor.close()#关闭光标
连接关闭()#关闭数据库连接
返回结果#返回列表列表

我喜欢@bryan和@foo-stack答案。如果您使用的是postgresql,并且使用的是
psycopg2
,那么在从连接创建光标时,您可以通过将光标工厂指定为
DictCursor
来实现相同的功能,如下所示:

cur=conn.cursor(cursor\u factory=psycopg2.extras.DictCursor)

因此,现在您可以执行sql查询,并获得一个字典来获取结果,而无需手动映射它们

cur.execute( sql_query )
results = cur.fetchall()

for row in results:
    print row['row_no']

请注意,您必须
导入psycopg2.extras
才能工作。

对于光标不可用的情况,例如,当某些函数调用或内部方法返回行时,您仍然可以使用row.cursor\u description创建字典表示

def row_to_dict(row):
    return dict(zip([t[0] for t in row.cursor_description], row))

我知道它很古老,我只是在重述别人已经说过的话。但我发现这种方法很好,因为它也很安全

def to_dict(行):
返回dict(zip([t[0]表示第行中的t.cursor_description],第行))
def查询(游标,查询,参数=[],游标函数=to_dict):
cursor.execute(查询,参数)
结果=[cursor.fetchall()中的行的cursor_func(行)]
返回结果
quotes=query(光标,“从缩写为“”的货币中选择*,[“USD”])

步骤如下:

  • 导入LIB:
  • 从本地数据库获取您的结果:

  • 是的,我确实注意到这是在中,但是这并没有改变我的要求。谢谢,但是当我不知道我的列名时,有一个通用的解决方案吗?是的,它被称为SQL语法。您可以在数据库中查询要查询的表的名称。我有w
    cur.execute( sql_query )
    results = cur.fetchall()
    
    for row in results:
        print row['row_no']
    
    def row_to_dict(row):
        return dict(zip([t[0] for t in row.cursor_description], row))
    
        from pandas import DataFrame
        import pyodbc
        import sqlalchemy
    
    db_file = r'xxx.accdb'
    odbc_conn_str = 'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=%s' % (db_file)
    
    conn = pyodbc.connect(odbc_conn_str)
    cur = conn.cursor() 
    qry = cur.execute("SELECT * FROM tbl")
    columns = [column[0] for column in cur.description]
    
    results = []
    for row in cur.fetchall():
     
       results.append(dict(zip(columns, row)))
    df = DataFrame(results) 
    df