Opened 15 years ago
Closed 15 years ago
#13119 closed (worksforme)
Can't pickle queryset
Reported by: | Paul Garner | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.2-beta |
Severity: | Keywords: | querySet pickle | |
Cc: | ego@… | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Was working ok until we upgraded from 1.1.1 to 1.2-beta-1 this morning.
Started getting the "can't pickle function object" error from this code:
class RatingDimensionManager(models.Manager): use_for_related_fields = True def get_for(self, obj): ct = ContentType.objects.get_for_model(obj)# cached by contentypes framework def from_db(obj): result = self.filter(content_type=ct.pk) cache.set('ratings:dimensions_for_type:%s:%s' % (hash(str(self.all().query)), ct.pk), result, settings.RATINGS_DIMENSIONS_FOR_CT_TTL) return result value = cache.get('ratings:dimensions_for_type:%s:%s' % (hash(str(self.all().query)), ct.pk), None) if value is None: value = from_db(obj) return value class RatingDimension(models.Model): content_type = models.ForeignKey(ContentType) label = models.CharField(max_length=256) sort_weight = models.IntegerField(default=100) average = models.FloatField(editable=False, default=0) objects = RatingDimensionManager() def __unicode__(self): return self.label class Meta(): ordering = ('sort_weight','label',)
Seems related to http://code.djangoproject.com/ticket/7506
Change History (8)
comment:1 by , 15 years ago
Resolution: | → worksforme |
---|---|
Status: | new → closed |
comment:3 by , 15 years ago
Thanks noisyboiler. It was the cache.set() call that was failing for me, and I am using memcached too.
However Russell is correct I believe, if I change this line:
result = self.filter(content_type=ct.pk)
to
result = self.filter(content_type__pk=ct.pk)
(as per #12924) then it starts working again. And also, that second form seems more correct anyway. Though as I said, it used to work in 1.1.1
comment:4 by , 15 years ago
Doesn't Pickle:
cars = Car.objects.filter(advertcarisnull=False)
Does Pickle:
cars = Car.objects.filter(advertcarpkisnull=False)
Both yield same results. Thank You Russell and anentropic.
comment:5 by , 15 years ago
Resolution: | worksforme |
---|---|
Status: | closed → reopened |
This isn't really a solution to the problem, or if it is a solution to the problem then the documentation on QuerySets is wrong. Either way, I don't believe this is solved.
According to documentation, this it valid:
the_region = TripRegion.objects.all()[0]
guides = DestinationGuide.objects.active().filter(region=the_region)
And sure, it is a valid way to perform a QuerySet lookup, however in order to make use of say caching which needs to pickle the query set we shouldn't have to change the QS lookup to:
guides = estinationGuide.objects.active().filter(regionpk=the_region.pk)
comment:6 by , 15 years ago
PLEASE use preview (and WikiFormatting). Most of the code posted in the previous few updates is completely indecipherable.
comment:7 by , 15 years ago
Fail.
*sigh*
This isn't really a solution to the problem, or if it is a solution to the problem then the documentation on Query Sets is incomplete. Either way, I don't believe this is solved.
the_region = TripRegion.objects.all()[0] guides = DestinationGuide.objects.active().filter(region=the_region)
This statement is valid, but will not work when pickled
pickle.dumps(guides) TypeError::can't pickle function objects
In order to get it to work, you need to change it to:
the_region = TripRegion.objects.all()[0] guides = DestinationGuide.objects.active().filter(region__pk=the_region.pk)
I specifically get this problem when trying to cache query set results.
It seems weird that I would have to change the way I do a lookup depending on whether I needed to cache the results or not.
comment:8 by , 15 years ago
Resolution: | → worksforme |
---|---|
Status: | reopened → closed |
I can't reproduce the problem reported by @ashchristopher on r12974. I used the following test in the queryset_pickle regression test:
def test_related_field_by_query(self): Group.objects.create(name="Ponies Who Own Maybachs") g = Group.objects.all()[0] self.assert_pickles(Event.objects.filter(group=g))
Works for me:
Two suggestions for providing bug reports:
Looking at your models, there's a good chance that this is a duplicate of #12924. I'm going to close this ticket worksforme (because it does). If it turns out that this isn't a duplicate of #12924, please reopen with a minimal example and a sample of how to induce the error.