django-sharding icon indicating copy to clipboard operation
django-sharding copied to clipboard

update_or_create and automatic routing

Open M1ha-Shvn opened this issue 7 years ago • 1 comments

Hi. Model.objects.update_or_create(key_field=key_value, defaults={}) is not routed automatically, when value existed. The reason is in it's realization:

    def update_or_create(self, defaults=None, **kwargs):
        """
        Looks up an object with the given kwargs, updating one with defaults
        if it exists, otherwise creates a new one.
        Returns a tuple (object, created), where created is a boolean
        specifying whether an object was created.
        """
        defaults = defaults or {}
        lookup, params = self._extract_model_params(defaults, **kwargs)
        self._for_write = True
        try:
            obj = self.get(**lookup)
        except self.model.DoesNotExist:
            obj, created = self._create_object_from_params(lookup, params)
            if created:
                return obj, created
        for k, v in six.iteritems(defaults):
            setattr(obj, k, v)
        obj.save(using=self.db)
        return obj, False

obj has been got correctly, but self.db returns 'default'. As a result obj.save(using=self.db) fails.

M1ha-Shvn avatar Jan 24 '18 07:01 M1ha-Shvn

I can take a look. To be honest, I haven't done too much work on the routing myself but I know how it works. I know there are some flaws with Django around self.db state as it is a single field that can only track where something is rather than where it will be and will sometimes throw away the using arg.

JBKahn avatar Jan 24 '18 15:01 JBKahn