Esempio n. 1
0
    def test_transactional_caching_behaviour(self):
        """
            The context cache exists so that transactional code becomes more sensible.

            Look at the following code:

            MyModel.objects.create(pk=1, value=0)

            with atomic():
                instance = MyModel.objects.get(pk=1)
                instance.value = 1
                instance.save()

                instance.refresh_from_db()
                assert(instance.value == 1)

            Without the context cache, this will raise AssertionError as 'value' will be zero.
            datastore.Get returns the state of the object at the start of the transaction.

            With the context cache, this will behave as intended as refresh_from_db() will hit the
            cache and return the thing you just saved.
        """

        instance = CachingTestModel.objects.create()

        @transaction.atomic()
        def b():
            obj = CachingTestModel.objects.get(pk=instance.pk)
            obj.comb1 += 1
            obj.save()

        @transaction.atomic()
        def a():
            obj = CachingTestModel.objects.get(pk=instance.pk)
            obj.comb1 += 1
            obj.save()
            b()

        # Make sure the context cache is enabled
        with disable_cache(memcache=True, context=False):
            a()

            instance.refresh_from_db()
            self.assertEqual(instance.comb1, 2)

        instance.comb1 = 0
        instance.save()

        # Now disable all caching
        with disable_cache(memcache=True, context=True):
            a()

            instance.refresh_from_db()

            # Should be one as the call to b() would trash the value set by a()
            self.assertEqual(instance.comb1, 1)
Esempio n. 2
0
    def map(entity, model, *args, **kwargs):
        """ The Clean mapper maps over all UniqueMarker instances. """

        alias = kwargs.get("db", "default")
        namespace = settings.DATABASES.get(alias, {}).get("NAMESPACE")

        model = decode_model(model)
        if not entity.key().id_or_name().startswith(model._meta.db_table + "|"):
            # Only include markers which are for this model
            return

        assert namespace == entity.namespace()
        with disable_cache():
            # At this point, the entity is a unique marker that is linked to an instance of 'model', now we should see if that instance exists!
            instance_id = entity["instance"].id_or_name()
            try:
                instance = model.objects.using(alias).get(pk=instance_id)
            except model.DoesNotExist:
                logging.info("Deleting unique marker {} because the associated instance no longer exists".format(entity.key().id_or_name()))
                datastore.Delete(entity)
                return

            # Get the possible unique markers for the entity, if this one doesn't exist in that list then delete it
            instance_entity = django_instance_to_entity(connections[alias], model, instance._meta.fields, raw=True, instance=instance, check_null=False)
            identifiers = unique_identifiers_from_entity(model, instance_entity, ignore_pk=True)
            identifier_keys = [datastore.Key.from_path(UniqueMarker.kind(), i, namespace=entity["instance"].namespace()) for i in identifiers]
            if entity.key() not in identifier_keys:
                logging.info("Deleting unique marker {} because the it no longer represents the associated instance state".format(entity.key().id_or_name()))
                datastore.Delete(entity)
Esempio n. 3
0
    def map(entity, model, *args, **kwargs):
        """ The Clean mapper maps over all UniqueMarker instances. """

        alias = kwargs.get("db", "default")
        namespace = settings.DATABASES.get(alias, {}).get("NAMESPACE", "")

        model = decode_model(model)
        if not entity.key().id_or_name().startswith(model._meta.db_table + "|"):
            # Only include markers which are for this model
            return

        assert namespace == entity.namespace()
        with disable_cache():
            # At this point, the entity is a unique marker that is linked to an instance of 'model', now we should see if that instance exists!
            instance_id = entity["instance"].id_or_name()
            try:
                instance = model.objects.using(alias).get(pk=instance_id)
            except model.DoesNotExist:
                logger.info("Deleting unique marker %s because the associated instance no longer exists", entity.key().id_or_name())
                datastore.Delete(entity)
                return

            # Get the possible unique markers for the entity, if this one doesn't exist in that list then delete it
            instance_entity, _ = django_instance_to_entities(connections[alias], instance._meta.fields, raw=True, instance=instance, check_null=False)
            identifiers = unique_identifiers_from_entity(model, instance_entity, ignore_pk=True)
            identifier_keys = [datastore.Key.from_path(UniqueMarker.kind(), i, namespace=entity["instance"].namespace()) for i in identifiers]
            if entity.key() not in identifier_keys:
                logger.info("Deleting unique marker %s because the it no longer represents the associated instance state", entity.key().id_or_name())
                datastore.Delete(entity)