diff options
-rw-r--r-- | lib/sqlalchemy/attributes.py | 15 | ||||
-rw-r--r-- | lib/sqlalchemy/engine.py | 8 | ||||
-rw-r--r-- | lib/sqlalchemy/mapping/mapper.py | 4 | ||||
-rw-r--r-- | lib/sqlalchemy/types.py | 24 | ||||
-rw-r--r-- | lib/sqlalchemy/util.py | 2 |
5 files changed, 39 insertions, 14 deletions
diff --git a/lib/sqlalchemy/attributes.py b/lib/sqlalchemy/attributes.py index 997b2c8f8..cd01faddd 100644 --- a/lib/sqlalchemy/attributes.py +++ b/lib/sqlalchemy/attributes.py @@ -214,7 +214,12 @@ class CallableProp(object): if passive: value = None else: - value = self.callable_() + try: + value = self.callable_() + except AttributeError, e: + # this catch/raise is because this call is frequently within an + # AttributeError-sensitive callstack + raise AssertionError("AttributeError caught in callable prop:" + str(e.args)) self.obj.__dict__[self.key] = value p = PropHistory(self.obj, self.key, **self.kwargs) @@ -223,11 +228,15 @@ class CallableProp(object): if passive: value = None else: - value = self.callable_() + try: + value = self.callable_() + except AttributeError, e: + # this catch/raise is because this call is frequently within an + # AttributeError-sensitive callstack + raise AssertionError("AttributeError caught in callable prop:" + str(e.args)) else: value = None p = self.manager.create_list(self.obj, self.key, value, readonly=self.live, **self.kwargs) - if not self.live and not passive: # set the new history list as the new attribute, discards ourself self.manager.attribute_history(self.obj)[self.key] = p diff --git a/lib/sqlalchemy/engine.py b/lib/sqlalchemy/engine.py index c804680e6..85005bb7d 100644 --- a/lib/sqlalchemy/engine.py +++ b/lib/sqlalchemy/engine.py @@ -852,10 +852,10 @@ class RowProxy: def __getitem__(self, key): return self.__parent._get_col(self.__row, key) def __getattr__(self, name): - try: - return self.__parent._get_col(self.__row, name) - except: - raise AttributeError + #try: + return self.__parent._get_col(self.__row, name) + #except: + # raise AttributeError def items(self): return [(key, getattr(self, key)) for key in self.keys()] def keys(self): diff --git a/lib/sqlalchemy/mapping/mapper.py b/lib/sqlalchemy/mapping/mapper.py index 0d3cbb300..32da013ac 100644 --- a/lib/sqlalchemy/mapping/mapper.py +++ b/lib/sqlalchemy/mapping/mapper.py @@ -812,7 +812,6 @@ class Mapper(object): list. if the instance already exists in the given identity map, its not added. in either case, executes all the property loaders on the instance to also process extra information in the row.""" - # look in main identity map. if its there, we dont do anything to it, # including modifying any of its related items lists, as its already # been exposed to being modified by the application. @@ -830,7 +829,6 @@ class Mapper(object): if self.extension.append_result(self, row, imap, result, instance, isnew, populate_existing=populate_existing): if result is not None: result.append_nohistory(instance) - return instance # look in result-local identitymap for it. @@ -857,11 +855,9 @@ class Mapper(object): # instances from the row and possibly populate this item. if self.extension.populate_instance(self, instance, row, identitykey, imap, isnew): self.populate_instance(instance, row, identitykey, imap, isnew, translate=False) - if self.extension.append_result(self, row, imap, result, instance, isnew, populate_existing=populate_existing): if result is not None: result.append_nohistory(instance) - return instance def populate_instance(self, instance, row, identitykey, imap, isnew, translate=True): diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py index 2aa67507d..ecf791a37 100644 --- a/lib/sqlalchemy/types.py +++ b/lib/sqlalchemy/types.py @@ -7,12 +7,16 @@ __all__ = [ 'TypeEngine', 'TypeDecorator', 'NullTypeEngine', 'INT', 'CHAR', 'VARCHAR', 'TEXT', 'FLOAT', 'DECIMAL', 'TIMESTAMP', 'DATETIME', 'CLOB', 'BLOB', 'BOOLEAN', 'String', 'Integer', 'Smallinteger', - 'Numeric', 'Float', 'DateTime', 'Date', 'Time', 'Binary', 'Boolean', 'Unicode', 'NULLTYPE', + 'Numeric', 'Float', 'DateTime', 'Date', 'Time', 'Binary', 'Boolean', 'Unicode', 'PickleType', 'NULLTYPE', 'SMALLINT', 'DATE', 'TIME' ] import sqlalchemy.util as util - +try: + import cPickle as pickle +except: + import pickle + class TypeEngine(object): basetypes = [] def __init__(self, *args, **kwargs): @@ -142,6 +146,22 @@ class Binary(TypeEngine): def get_constructor_args(self): return {'length':self.length} +class PickleType(Binary): + def __init__(self, protocol=pickle.HIGHEST_PROTOCOL): + """allows the pickle protocol to be specified""" + self.protocol = protocol + def convert_result_value(self, value, engine): + if value is None: + return None + buf = Binary.convert_result_value(self, value, engine) + return pickle.loads(str(buf)) + def convert_bind_param(self, value, engine): + if value is None: + return None + return Binary.convert_bind_param(self, pickle.dumps(value, self.protocol), engine) + def get_constructor_args(self): + return {} + class Boolean(TypeEngine): pass diff --git a/lib/sqlalchemy/util.py b/lib/sqlalchemy/util.py index 85bbfdc5a..44209b104 100644 --- a/lib/sqlalchemy/util.py +++ b/lib/sqlalchemy/util.py @@ -397,7 +397,7 @@ class HistoryArraySet(UserList.UserList): def has_item(self, item): return self.records.has_key(item) def __setitem__(self, i, item): - if self._setrecord(a): + if self._setrecord(item): self.data[i] = item def __delitem__(self, i): self._delrecord(self.data[i]) |