kiddouk / redisco

A Python Library for Simple Models and Containers Persisted in Redis
MIT License
438 stars 78 forks source link

Wasteful EXIST command #17

Open dmk23 opened 12 years ago

dmk23 commented 12 years ago

Right now object loading generates an unnecessary EXISTS command. It is wasteful because the subsequent call to HGETALL can be interpreted to ascertain object's existence.

I've made a change to the model id setter and the method that calls it to fix the problem:

    @id.setter
    def id(self, val):
        """
        Setting the id for the object will fetch it from the datastorage;
        If nothing in the datasore, do nothing
        """
        self._id = str(val)
        stored_attrs = self.db.hgetall(self.key())
        if not stored_attrs:
            self._id = None     # key does not exist, set ID to nothing
        else:
            attrs = self.attributes.values()
            for att in attrs:
                if att.name in stored_attrs and not isinstance(att, Counter):
                    att.__set__(self, att.typecast_for_read(stored_attrs[att.name]))
def get_by_id(self, id):
    if (self._filters or self._exclusions or self._zfilters) and str(id) not in self._set:
        return
    obj = self._get_item_with_id(id)
    return obj if obj.id else None

import redisco.models.modelset
redisco.models.modelset.ModelSet.get_by_id = get_by_id

Additionally @classmethod exists currently does not respect DB setting per class. It should use the classes' DB setting instead of always relying on a global object.

72squared commented 11 years ago

At very least, defer the exist check till after fetching data instead of before. if data comes back, you don't need to check exists. If the key is empty (which is rare), then you can do the exists check.