def end(self, element): super().end(element) if element.tag == self.tag: nursery = get_nursery() logger.info("cache size: %d", len(nursery.cache.keys())) nursery.clear_cache()
def clear_workbasket(workbasket): """ Deletes all objects connected to the workbasket while preserving the workbasket itself. Due to the DB relations this has to be done in a specific order. - First the Tracked Models must be deleted in reverse order. - As these are deleted their VersionGroups must be deleted or reset to have the previous version as current. - Also if any of these exist within the cache they must be removed from the cache. - Second Transactions are deleted. """ nursery = get_nursery() for obj in workbasket.tracked_models.order_by("-pk"): version_group = obj.version_group obj.delete() nursery.remove_object_from_cache(obj) if version_group.versions.count() == 0: version_group.delete() else: version_group.current_version = version_group.versions.order_by( "-pk", ).first() version_group.save() workbasket.transactions.all().delete()
def delete_workbasket(workbaset): """ Deletes all objects connected to the workbasket and the workbasket itself. Due to the DB relations this has to be done in a specific order. - First the GoodsNomenclatureIndentNodes must be deleted. - Second the Tracked Models must be deleted in reverse order. - As these are deleted their VersionGroups must be deleted or reset to have the previous version as current. - Also if any of these exist within the cache they must be removed from the cache. - Third Transactions are deleted. - Fourth the WorkBasket is deleted """ nursery = get_nursery() GoodsNomenclatureIndentNode.objects.filter( creating_transaction__workbasket=workbaset).delete() for obj in workbaset.tracked_models.order_by("-pk"): version_group = obj.version_group obj.delete() nursery.remove_object_from_cache(obj) if version_group.versions.count() == 0: version_group.delete() else: version_group.current_version = version_group.versions.order_by( "-pk").first() version_group.save() workbaset.transactions.all().delete() workbaset.delete()
def check( factory: Callable[[], TrackedModel], serializer: Type[TrackedModelSerializer], record_group: Sequence[str] = None, workflow_status: WorkflowStatus = WorkflowStatus.PUBLISHED, ) -> TrackedModel: get_nursery().cache.clear() settings.SKIP_WORKBASKET_VALIDATION = True model = factory() model_class = type(model) assert isinstance( model, TrackedModel, ), "A factory that returns an object instance needs to be provided" xml = generate_test_import_xml( [serializer(model, context={"format": "xml"}).data], ) import_xml(xml, workflow_status, record_group) db_kwargs = model.get_identifying_fields() workbasket = WorkBasket.objects.last() assert workbasket is not None try: imported = model_class.objects.approved_up_to_transaction( workbasket.current_transaction, ).get(**db_kwargs) except model_class.DoesNotExist: if model.update_type == UpdateType.DELETE: imported = ( model_class.objects.versions_up_to(workbasket.current_transaction) .filter(**db_kwargs) .last() ) else: raise assert_records_match(model, imported) return imported
def check( model: Union[TrackedModel, Type[DjangoModelFactory]], serializer: Type[TrackedModelSerializer], ) -> TrackedModel: get_nursery().cache.clear() settings.SKIP_WORKBASKET_VALIDATION = True if isinstance(model, type) and issubclass(model, DjangoModelFactory): model = model.build(update_type=UpdateType.CREATE) assert isinstance( model, TrackedModel, ), "Either a factory or an object instance needs to be provided" xml = generate_test_import_xml( serializer(model, context={"format": "xml"}).data, ) process_taric_xml_stream( xml, username=valid_user.username, status=WorkflowStatus.PUBLISHED, ) db_kwargs = model.get_identifying_fields() imported = model.__class__.objects.get_latest_version(**db_kwargs) checked_fields = ( set(field.name for field in imported._meta.fields) - set(field.name for field in TrackedModel._meta.fields) - {"trackedmodel_ptr"} ) for field in checked_fields: imported_value = getattr(imported, field) source_value = getattr(model, field) assert ( imported_value == source_value ), f"imported '{field}' ({imported_value} - {type(imported_value)}) does not match source '{field}' ({source_value} - {type(source_value)})" return imported
class Writable: """ A parser which implements the Writable interface can write its changes to the database. Not all TARIC3 elements correspond to database entities (particularly simple text elements, but also envelopes and app.messages). """ nursery = get_nursery() def create(self, data: Mapping[str, Any], transaction_id: int): """Preps the given data as a create record and submits it to the nursery for processing.""" data.update(update_type=UpdateType.CREATE) dispatch_object = { "data": data, "tag": self.tag.name, "transaction_id": transaction_id, } self.nursery.submit(dispatch_object) def update(self, data: Mapping[str, Any], transaction_id: int): """Update a DB record with provided data.""" data.update(update_type=UpdateType.UPDATE.value) dispatch_object = { "data": data, "tag": self.tag.name, "transaction_id": transaction_id, } self.nursery.submit(dispatch_object) def delete(self, data: Mapping[str, Any], transaction_id: int): """Delete a DB record with provided data.""" data.update(update_type=UpdateType.DELETE.value) dispatch_object = { "data": data, "tag": self.tag.name, "transaction_id": transaction_id, } self.nursery.submit(dispatch_object)
def object_nursery() -> TariffObjectNursery: nursery = get_nursery() yield nursery nursery.cache.clear()