生成PyODBC查询作为词典的更一般方法?

时间:2013-05-21 16:37:04

标签: python database dictionary pyodbc

以下是我根据数据库查询结果创建字典的一般类通用方法:

def make_schema_dict(self):
    schema = [i[2] for i in self.cursor.tables()
              if i[2].startswith('tbl_') or i[2].startswith('vw_')]

    self.schema = {table: {'scheme': [row.column_name for row
                                      in self.cursor.columns(table)]}
                   for table in schema}

def last_table_query_as_dict(self, table):
    return {'data': [{col: row.__getattribute__(col) for col in self.schema[table]['scheme']
                      if col != 'RowNum'} for row in self.cursor.fetchall()]}

不幸的是,你可以看到,有许多并发症。

例如,查询多个表时;一些hackish lambdas需要生成结果字典。

你能想到一些更通用的方法吗?

2 个答案:

答案 0 :(得分:6)

您应该可以使用row.cursor_description来简化这一过程。这应该会为您提供结果的词典列表:

    [{c[0]: v for (c, v) in zip(row.cursor_description, row)} for row in self.cursor.fetchall()]

答案 1 :(得分:2)

在这个帖子中可以找到一个简洁的解决方案:https://groups.google.com/forum/?fromgroups#!topic/pyodbc/BVIZBYGXNsk

想法的根源是子类Connection使用自定义Cursor类,让Cursor类自动为你构造dicts。我称之为奇特的pythonic解决方案。你也可以只有一个额外的函数fetchonedict()并扩展Cursor类而不是覆盖,这样你就可以保留默认行为。

class ConnectionWrapper(object): 
    def __init__(self, cnxn): 
        self.cnxn = cnxn 

    def __getattr__(self, attr): 
        return getattr(self.cnxn, attr) 

    def cursor(self): 
        return CursorWrapper(self.cnxn.cursor()) 

class CursorWrapper(object): 
    def __init__(self, cursor): 
        self.cursor = cursor 

    def __getattr__(self, attr): 
        return getattr(self.cursor, attr) 

    def fetchone(self): 
        row = self.cursor.fetchone() 
        if not row: 
            return None 
        return dict((t[0], value) for t, value in zip (self.cursor.description, row)) 

此外,虽然不适用于PyODBC,但如果您需要一些设计灵感,请查看此stackoverflow答案,以获取指向MySQL和OurSQL的DictCursor类的链接。