diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2006-03-25 02:25:59 +0000 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2006-03-25 02:25:59 +0000 |
commit | 34d961cde0267f472850f2ceb09b3733033c62d6 (patch) | |
tree | c1ba73618ff398346766796d6e13af9023ea5084 /lib/sqlalchemy/mapping | |
parent | f922fa7b6032370c8cf86c0710727aeee37baff8 (diff) | |
download | sqlalchemy-34d961cde0267f472850f2ceb09b3733033c62d6.tar.gz |
got some support for mapping to a select that only selects some of the columns of an underlying table
Diffstat (limited to 'lib/sqlalchemy/mapping')
-rw-r--r-- | lib/sqlalchemy/mapping/mapper.py | 32 | ||||
-rw-r--r-- | lib/sqlalchemy/mapping/unitofwork.py | 2 |
2 files changed, 26 insertions, 8 deletions
diff --git a/lib/sqlalchemy/mapping/mapper.py b/lib/sqlalchemy/mapping/mapper.py index 5b56358ba..907d412fa 100644 --- a/lib/sqlalchemy/mapping/mapper.py +++ b/lib/sqlalchemy/mapping/mapper.py @@ -18,6 +18,11 @@ import weakref # a dictionary mapping classes to their primary mappers mapper_registry = weakref.WeakKeyDictionary() +# a constant returned by _getattrbycolumn to indicate +# this mapper is not handling an attribute for a particular +# column +NO_ATTRIBUTE = object() + class Mapper(object): """Persists object instances to and from schema.Table objects via the sql package. Instances of this class should be constructed through this package's mapper() or @@ -534,19 +539,25 @@ class Mapper(object): params = {} return self.instances(statement.execute(**params), **kwargs) - def _getpropbycolumn(self, column): + def _getpropbycolumn(self, column, raiseerror=True): try: prop = self.columntoproperty[column.original] except KeyError: try: prop = self.props[column.key] + if not raiseerror: + return None raise InvalidRequestError("Column '%s.%s' is not available, due to conflicting property '%s':%s" % (column.table.name, column.name, column.key, repr(prop))) except KeyError: + if not raiseerror: + return None raise InvalidRequestError("No column %s.%s is configured on mapper %s..." % (column.table.name, column.name, str(self))) return prop[0] - def _getattrbycolumn(self, obj, column): - prop = self._getpropbycolumn(column) + def _getattrbycolumn(self, obj, column, raiseerror=True): + prop = self._getpropbycolumn(column, raiseerror) + if prop is None: + return NO_ATTRIBUTE return prop.getattr(obj) def _setattrbycolumn(self, obj, column, value): @@ -615,7 +626,9 @@ class Mapper(object): # doing an UPDATE ? get the history for the attribute, with "passive" # so as not to trigger any deferred loads. if there is a new # value, add it to the bind parameters - prop = self._getpropbycolumn(col) + prop = self._getpropbycolumn(col, False) + if prop is None: + continue history = prop.get_history(obj, passive=True) if history: a = history.added_items() @@ -629,7 +642,9 @@ class Mapper(object): # default. if its None and theres no default, we still might # not want to put it in the col list but SQLIte doesnt seem to like that # if theres no columns at all - value = self._getattrbycolumn(obj, col) + value = self._getattrbycolumn(obj, col, False) + if value is NO_ATTRIBUTE: + continue if col.default is None or value is not None: params[col.key] = value @@ -682,13 +697,16 @@ class Mapper(object): clause.clauses.append(p == self._getattrbycolumn(obj, p)) row = table.select(clause).execute().fetchone() for c in table.c: - if self._getattrbycolumn(obj, c) is None: + if self._getattrbycolumn(obj, c, False) is None: self._setattrbycolumn(obj, c, row[c]) else: for c in table.c: if c.primary_key or not params.has_key(c.name): continue - if self._getattrbycolumn(obj, c) != params.get_original(c.name): + v = self._getattrbycolumn(obj, c, False) + if v is NO_ATTRIBUTE: + continue + elif v != params.get_original(c.name): self._setattrbycolumn(obj, c, params.get_original(c.name)) def delete_obj(self, objects, uow): diff --git a/lib/sqlalchemy/mapping/unitofwork.py b/lib/sqlalchemy/mapping/unitofwork.py index 1e5388933..fc589f65b 100644 --- a/lib/sqlalchemy/mapping/unitofwork.py +++ b/lib/sqlalchemy/mapping/unitofwork.py @@ -737,7 +737,7 @@ class UOWTask(object): def _repr_task(task): if task.mapper is not None: if task.mapper.__class__.__name__ == 'Mapper': - name = task.mapper.class_.__name__ + "/" + task.mapper.primarytable.id + "/" + str(id(task.mapper)) + name = task.mapper.class_.__name__ + "/" + str(task.mapper.primarytable) + "/" + str(id(task.mapper)) else: name = repr(task.mapper) else: |