Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

# Wraps DB-API 2.0 query results to provide 

# a nice list and dictionary interface. 

# 

# Copyright (C) 2002  Dr. Conan C. Albrecht <conan_albrecht@byu.edu> 

# 

# This library is free software; you can redistribute it and/or 

# modify it under the terms of the GNU Lesser General Public 

# License as published by the Free Software Foundation; either 

# version 2.1 of the License, or (at your option) any later version. 

# 

# This library is distributed in the hope that it will be useful, 

# but WITHOUT ANY WARRANTY; without even the implied warranty of 

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 

# Lesser General Public License for more details. 

# 

# You should have received a copy of the GNU Lesser General Public 

# License along with this library; if not, write to the Free Software 

# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

 

 

# I created this class and related functions because I like accessing 

# database results by field name rather than field number.  Accessing 

# by field number has many problems: code is less readable, code gets 

# broken when field positions change or fields are added or deleted from 

# the query, etc. 

# 

# This class should have little overhead if you are already using fetchall(). 

# It wraps each result row in a ResultRow class which allows you to 

# retrieve results via a dictionary interface (by column name).  The regular 

# list interface (by column number) is also provided. 

# 

# I can't believe the DB-API 2.0 api didn't include dictionary-style results. 

# I'd love to see the reasoning behind not requiring them of database 

# connection classes. 

 

# This module comes from: 

# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/163605 

 

def get_rows(cursor, sql): 

    """Return a list of ResultRow objects from an SQL query.""" 

 

    # run the query 

    cursor.execute(sql) 

 

    # return the list 

    return getdict(cursor.fetchall(), cursor.description) 

 

 

def getdict(results, description): 

    """Return the list of DBRows in `results` with a given description.""" 

 

    # get the field names 

    fields = {} 

    for i in range(len(description)): 

        fields[description[i][0]] = i 

 

    # generate the list of DBRow objects 

    rows = [] 

    for result in results: 

        rows.append(DBRow(result, fields)) 

 

    # return to the user 

    return rows 

 

 

class DBRow(object): 

    """A single row in a result set. 

 

    Each DBRow has a dictionary-style and list-style interface. 

    """ 

 

    def __init__(self, row, fields): 

        """Called by ResultSet function.  Don't call directly""" 

        self.fields = fields 

        self.row = row 

        self._extra_fields = {} 

 

    def __repr__(self): 

        return "<DBrow with %s fields>" % len(self) 

 

    def __str__(self): 

        """Return a string representation""" 

        return str(self.row) 

 

    def __getattr__(self, attr): 

        return self.row[self.fields[attr]] 

 

    def set_extra_attr(self, attr, value): 

        self._extra_fields[attr] = value 

 

    def __getitem__(self, key): 

        """Return the value of the named column""" 

        if isinstance(type(key), int):  # if a number 

            return self.row[key] 

        else:  # a field name 

            return self.row[self.fields[key]] 

 

    def __setitem__(self, key, value): 

        """Not used in this implementation""" 

        raise TypeError("can't set an item of a result set") 

 

    def __getslice__(self, i, j): 

        """Return the value of the numbered column""" 

        return self.row[i: j] 

 

    def __setslice__(self, i, j, list): 

        """Not used in this implementation""" 

        raise TypeError("can't set an item of a result set") 

 

    def keys(self): 

        """Return the field names""" 

        return list(self.fields.keys()) 

 

    def keymappings(self): 

        """Return a dictionary of the keys and their indices in the row""" 

        return self.fields 

 

    def has_key(self, key): 

        """Return whether the given key is valid""" 

        return key in self.fields 

 

    def as_dict(self): 

        d = {} 

        for field_name, pos in self.fields.items(): 

            d[field_name] = self.row[pos] 

        for field_name, field in self._extra_fields.items(): 

            d[field_name] = field 

        return d 

 

    def __len__(self): 

        """Return how many columns are in this row""" 

        return len(self.row) 

 

    def __bool__(self): 

        return len(self.row) != 0 

 

    def __eq__(self, other): 

        # Error if other is not set 

        if other is None: 

            return False 

        return self.fields == other.fields