def _set_iterable(self, state, iterable, adapter=None): """Set a collection value from an iterable of state-bearers. ``adapter`` is an optional callable invoked with a CollectionAdapter and the iterable. Should return an iterable of state-bearing instances suitable for appending via a CollectionAdapter. Can be used for, e.g., adapting an incoming dictionary into an iterator of values rather than keys. """ # pulling a new collection first so that an adaptation exception does # not trigger a lazy load of the old collection. new_collection, user_data = self._build_collection(state) if adapter: new_values = list(adapter(new_collection, iterable)) else: new_values = list(iterable) old = self.get(state) # ignore re-assignment of the current collection, as happens # implicitly with in-place operators (foo.collection |= other) if old is iterable: return if self.key not in state.committed_state: state.committed_state[self.key] = self.copy(old) old_collection = self.get_collection(state, old) state.dict[self.key] = user_data state.modified = True collections.bulk_replace(new_values, old_collection, new_collection) old_collection.unlink(old)
def _set_iterable(self, state, dict_, iterable, adapter=None): """Set a collection value from an iterable of state-bearers. ``adapter`` is an optional callable invoked with a CollectionAdapter and the iterable. Should return an iterable of state-bearing instances suitable for appending via a CollectionAdapter. Can be used for, e.g., adapting an incoming dictionary into an iterator of values rather than keys. """ # pulling a new collection first so that an adaptation exception does # not trigger a lazy load of the old collection. new_collection, user_data = self._initialize_collection(state) if adapter: new_values = list(adapter(new_collection, iterable)) else: new_values = list(iterable) old = self.get(state, dict_, passive=PASSIVE_ONLY_PERSISTENT) if old is PASSIVE_NO_RESULT: old = self.initialize(state, dict_) elif old is iterable: # ignore re-assignment of the current collection, as happens # implicitly with in-place operators (foo.collection |= other) return # place a copy of "old" in state.committed_state state.modified_event(dict_, self, old, True) old_collection = getattr(old, '_sa_adapter') dict_[self.key] = user_data collections.bulk_replace(new_values, old_collection, new_collection) old_collection.unlink(old)
def _set_iterable(self, state, dict_, iterable, adapter=None): collection_history = self._modified_event(state, dict_) new_values = list(iterable) if state.has_identity: old_collection = list(self.get(state, dict_)) else: old_collection = [] collections.bulk_replace( new_values, DynCollectionAdapter(self, state, old_collection), DynCollectionAdapter(self, state, new_values))
def _set_iterable(self, state, dict_, iterable, adapter=None): collection_history = self._modified_event(state, dict_) new_values = list(iterable) if _state_has_identity(state): old_collection = list(self.get(state, dict_)) else: old_collection = [] collections.bulk_replace(new_values, DynCollectionAdapter(self, state, old_collection), DynCollectionAdapter(self, state, new_values))