Package elisa :: Package extern :: Module db_row
[hide private]
[frames] | no frames]

Source Code for Module elisa.extern.db_row

  1  # Wraps DB-API 2.0 query results to provide a nice list and dictionary interface. 
  2  # Copyright (C) 2002  Dr. Conan C. Albrecht <conan_albrecht@byu.edu> 
  3  # 
  4  # This library is free software; you can redistribute it and/or 
  5  # modify it under the terms of the GNU Lesser General Public 
  6  # License as published by the Free Software Foundation; either 
  7  # version 2.1 of the License, or (at your option) any later version. 
  8  # 
  9  # This library is distributed in the hope that it will be useful, 
 10  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 12  # Lesser General Public License for more details. 
 13  # 
 14  # You should have received a copy of the GNU Lesser General Public 
 15  # License along with this library; if not, write to the Free Software 
 16  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 17   
 18   
 19  # I created this class and related functions because I like accessing 
 20  # database results by field name rather than field number.  Accessing 
 21  # by field number has many problems: code is less readable, code gets 
 22  # broken when field positions change or fields are added or deleted from 
 23  # the query, etc. 
 24  # 
 25  # This class should have little overhead if you are already using fetchall(). 
 26  # It wraps each result row in a ResultRow class which allows you to 
 27  # retrieve results via a dictionary interface (by column name).  The regular 
 28  # list interface (by column number) is also provided. 
 29  # 
 30  # I can't believe the DB-API 2.0 api didn't include dictionary-style results. 
 31  # I'd love to see the reasoning behind not requiring them of database connection 
 32  # classes. 
 33   
 34  # This module comes from: 
 35  # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/163605 
 36   
37 -def get_rows(cursor, sql):
38 """Returns a list of ResultRow objects based upon a connected cursor 39 and a query sql string to execute""" 40 41 # run the query 42 cursor.execute(sql) 43 44 # return the list 45 return getdict(cursor.fetchall(), cursor.description)
46 47
48 -def getdict(results, description):
49 """Returns a list of DBRow objects based upon already retrieved results 50 and the query description returned from cursor.description""" 51 52 # get the field names 53 fields = {} 54 for i in range(len(description)): 55 fields[description[i][0]] = i 56 57 # generate the list of DBRow objects 58 rows = [] 59 for result in results: 60 rows.append(DBRow(result, fields)) 61 62 # return to the user 63 return rows
64 65
66 -class DBRow:
67 """A single row in a result set with a dictionary-style and list-style interface""" 68
69 - def __init__(self, row, fields):
70 """Called by ResultSet function. Don't call directly""" 71 self.row = row 72 self.fields = fields
73
74 - def __repr__(self):
75 return "<DBrow with %s fields>" % len(self)
76
77 - def __str__(self):
78 """Returns a string representation""" 79 return str(self.row)
80
81 - def __getattr__(self, attr):
82 return self.row[self.fields[attr]]
83
84 - def __getitem__(self, key):
85 """Returns the value of the named column""" 86 if type(key) == type(1): # if a number 87 return self.row[key] 88 else: # a field name 89 return self.row[self.fields[key]]
90
91 - def __setitem__(self, key, value):
92 """Not used in this implementation""" 93 raise TypeError, "can't set an item of a result set"
94
95 - def __getslice__(self, i, j):
96 """Returns the value of the numbered column""" 97 return self.row[i: j]
98
99 - def __setslice__(self, i, j, list):
100 """Not used in this implementation""" 101 raise TypeError, "can't set an item of a result set"
102
103 - def keys(self):
104 """Returns the field names""" 105 return self.fields.keys()
106
107 - def keymappings(self):
108 """Returns a dictionary of the keys and their indices in the row""" 109 return self.fields
110
111 - def has_key(self, key):
112 """Returns whether the given key is valid""" 113 return self.fields.has_key(key)
114
115 - def __len__(self):
116 """Returns how many columns are in this row""" 117 return len(self.row)
118
119 - def __nonzero__(self):
120 return len(self.row) != 0
121
122 - def __eq__(self, other):
123 ## Error if other is not set 124 if other == None: 125 return False 126 return self.fields == other.fields
127