import sqlalchemy.schema as schema
class Mapper:
- def __init__(self, class_, table, properties, identitymap = None):
+ def __init__(self, class_, table, properties = None, identitymap = None):
self.class_ = class_
self.table = table
+
+ self.props = {}
+
if properties is not None:
- self.properties = properties
+ for key, column in properties.iteritems():
+ desc = (key, column)
+ self.props["key_" + key] = desc
+ self.props["column_" + column.label] = desc
+ self.props["column_" + column.name] = desc
else:
- properties = {}
for column in table.columns:
- properties[column.name] = column
+ desc = (column.name, column)
+ self.props["key_" + column.name] = desc
+ self.props["column_" + column.label] = desc
+ self.props["column_" + column.name] = desc
if identitymap is not None:
self.identitymap = identitymap
def _create(self, row):
instance = self.class_()
- for key, column in self.properties.iteritems:
- # column label or column name ? depends on the query
- setattr(instance, key, row[value.label])
+ for desc in self.props.values():
+ setattr(instance, desc[0], row[desc[1].name])
return instance
def instance(self, row):
"""returns an instance of the object based on the given ID."""
pass
- def _select_whereclause(self, whereclause, **params):
- statement = select([self.table], whereclause)
+ def _select_whereclause(self, whereclause = None, **params):
+ statement = sql.select([self.table], whereclause)
return self._select_statement(statement, **params)
def _select_statement(self, statement, **params):
result = []
- cursor = statement.execute(**params)
+ cursor = ResultProxy(statement.execute(**params))
while True:
row = cursor.fetchone()
if row is None:
result.append(self.instance(row))
return result
- def select(self, arg, **params):
+ def select(self, arg = None, **params):
"""selects instances of the object from the database.
arg can be any ClauseElement, which will form the criterion with which to
will be executed and its resulting rowset used to build new object instances.
in this case, the developer must insure that an adequate set of columns exists in the
rowset with which to build new object instances."""
- if isinstance(arg, sql.Select):
+ if arg is not None and isinstance(arg, sql.Select):
return self._select_statement(arg, **params)
else:
return self._select_whereclause(arg, **params)
def delete(self, whereclause = None, **params):
pass
+class ResultProxy:
+ def __init__(self, cursor):
+ self.cursor = cursor
+ metadata = cursor.description
+ self.props = {}
+ i = 0
+ for item in metadata:
+ self.props[item[0]] = i
+ self.props[i] = i
+ i+=1
+
+ def fetchone(self):
+ row = self.cursor.fetchone()
+ if row is not None:
+ return RowProxy(self, row)
+ else:
+ return None
+
+class RowProxy:
+ def __init__(self, parent, row):
+ self.parent = parent
+ self.row = row
+ def __getitem__(self, key):
+ return self.row[self.parent.props[key]]
class IdentityMap:
def __init__(self):
to the row, returns a corrseponding object instance, if any, from the identity
map. the primary keys specified in the table will be used to indicate which
columns from the row form the effective key of the instance."""
- key = (class_, table, tuple([row[column.label] for column in table.primary_keys]))
+ key = (class_, table, tuple([row[column.name] for column in table.primary_keys]))
try:
- return self.map(key)
+ return self.map[key]
except KeyError:
- return self.map.setdefault(key, creator())
+ return self.map.setdefault(key, creator(row))