def update(self, new_details, old_details=None):
        
        ''' a method to upsert changes to a record in the table
        
        :param new_details: dictionary with updated record fields
        :param old_details: [optional] dictionary with original record fields 
        :return: list of dictionaries with updated field details
        
        NOTE:   if old_details is empty, method will poll database for the
                most recent version of the record with which to compare the
                new details for changes
        '''
        
        title = '%s.update' % self.__class__.__name__
        
    # validate inputs
        input_fields = {
            'new_details': new_details,
            'old_details': old_details
        }
        for key, value in input_fields.items():
            if value:
                object_title = '%s(%s=%s)' % (title, key, str(value))
                self.fields.validate(value, '.%s' % key, object_title)
        if old_details:
            if new_details['id'] != old_details['id']:
                raise ValueError('%s old_details["id"] value must match new_details["id"]'  % title)
    
    # extract primary key
        primary_key = new_details['id']
    
    # # handle missing id
    #     if not '.id' in self.model.keyMap.keys():
    #         del new_details['id']
    #         if old_details:
    #             del old_details['id']
    
    # validate new details against record model
        new_details = self.model.validate(new_details)
            
    # retrieve old record if not specified
        if not old_details:
            try:
                old_details = self.read(primary_key)
            except:
                raise ValueError('%s new_details["id"] does not exist.' % title)
                
    # determine record differences
        from labpack.parsing.comparison import compare_records
        update_list = compare_records(new_details, old_details)
    
    # construct update keywords
        update_kwargs = {}
        for update in update_list:
            if update['action'] not in ('DELETE', 'REMOVE'):
                current_details = new_details
                save_path = ''
                for segment in update['path']:
                    if save_path:
                        save_path += '.'
                    save_path += segment
                    if isinstance(current_details[segment], dict):
                        current_details = current_details[segment]
                        continue
                    elif isinstance(current_details[segment], list):
                        update_kwargs[save_path] = pickle.dumps(current_details[segment])
                        break
                    else:
                        update_kwargs[save_path] = current_details[segment]
            else:
                current_details = old_details
                save_path = ''
                for i in range(len(update['path'])):
                    segment = update['path'][i]
                    if save_path:
                        save_path += '.'
                    save_path += segment
                    if update['action'] == 'DELETE' and i + 1 == len(update['path']):
                        update_kwargs[save_path] = None
                    elif isinstance(current_details[segment], dict):
                        current_details = current_details[segment]
                        continue
                    elif isinstance(current_details[segment], list):
                        update_kwargs[save_path] = pickle.dumps(new_details[segment])
                        break
                    else:
                        update_kwargs[save_path] = None
            
    # send update command
        if update_kwargs:
            update_statement = self.table.update(self.table.c.id==primary_key).values(**update_kwargs)
            self.session.execute(update_statement)
        
        return update_list