more sqlalchemy api fixes
[invirt/packages/invirt-database.git] / python / database / record.py
1 import sqlalchemy.orm.util as util
2
3 class Record(object):
4     _identity_field = None
5     _default = {}
6     _format = {}
7
8     def get(self, field):
9         v = getattr(self, field, None)
10         if v is None:
11             return self._default.get(field)
12         return v
13
14     def _formatField(self, field):
15         v = self.get(field)
16         func = self._format.get(field)
17         if func:
18             return func(v)
19         if callable(v):
20             v = v()
21         if not hasattr(v, '__iter__'):
22             return repr(v)
23         if len(v) == 0:
24             return '[]'
25         return '[%d x %s]'%(len(v), type(v[0]).__name__)
26
27     @classmethod
28     def _ignore(cls):
29         return [cls._identity_field]
30
31     def _fields(self):
32         ignore = self._ignore()
33         keys = sorted(util.class_mapper(type(self)).mapped_table.c.keys())
34         return [(k,self._formatField(k)) for k in keys if k not in ignore]
35
36     def __repr__(self):
37         classname = self.__class__.__name__
38
39         if self._identity_field:
40             identity = self.__dict__.get(self._identity_field)
41             identity = ' ' + (identity and repr(identity) or 'hash=%X'%hash(self))
42         else:
43             identity = ''
44
45         payload = " ".join(["%s=%s" % (k, v) for k,v in self._fields()])
46         if len(payload) > 0:
47             payload = ": "+payload
48
49         return "<%s%s%s>" % (classname, identity, payload)