#20157 closed Bug (fixed)
Cannot pickle prefetched queryset on model with callable default datetime.datetime.now
Reported by: | thomaspurchas | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.5 |
Severity: | Normal | Keywords: | pickle, queryset |
Cc: | thomaspurchas, Florian Apolloner, bmispelon@… | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
With the follow models
class Post(models.Model): post_date = models.DateTimeField(default=datetime.datetime.now) class Material(models.Model): post = models.ForeignKey(Post, related_name='materials')
When the following is run
post = Post.objects.create() posts = Post.objects.all() posts = posts.prefetch_related('materials') pickle.dumps(posts)
Pickle returns the following error PicklingError: Can't pickle <built-in method now of type object at 0x10782c640>: it's not found as __main__.now
.
This appears to be some sort of repeat of issue #13328, and it only affects 1.5. Using bisect I have found the first commit that breaks this 056ace0f395a.
I have also attached a complete traceback.
Attachments (1)
Change History (14)
by , 12 years ago
Attachment: | traceback.txt added |
---|
comment:1 by , 12 years ago
Cc: | added |
---|
comment:2 by , 12 years ago
I think (!!, not 100% sure, but it seems like a valid start) 69597e5bcc89aadafd1b76abf7efab30ee0b8b1a fixed it in master.
comment:3 by , 12 years ago
Cc: | added |
---|
comment:4 by , 12 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:5 by , 12 years ago
Cc: | added |
---|
comment:6 by , 12 years ago
Yeah sorry, for some reason it never crossed my mind to check the master. The bug appears to be fixed in master.
comment:7 by , 12 years ago
Just to make sure this wasn't missed somewhere, but by default, auth.user uses timezone.now which is exhibiting the same issues (for me) with trying to pickle it, even indirectly with vary headers in the cache.
comment:8 by , 12 years ago
In theory this could be marked as release blocker because it is a regression. However, the commit which fixed it is a large refactor, which probably would not be a good idea to backport.
Do we have code in Django that pickels auth.User querysets, or any querysets? Is it possible to work around the issue faced by anonymous?
comment:9 by , 12 years ago
For what its worth, I think this is a relatively severe issue if your Django app relies on the low level cache api and you were caching querysets. Is anyone aware of a workaround for the time being? I'm assuming whatever is in master is going out in 1.5.2.
comment:11 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:12 by , 12 years ago
I am seeing this as well without any callable defaults. Take the model below.
class Profile(models.Model): user = models.ForeignKey(User, primary_key=True, related_name='profile')
Then the following is not pickleable
User.objects.all().prefetch_related('profile')
I'm going to test the posted fix, but just wondering if that fix will make it into 1.5.2 as this is currently blocking our team from upgrading to Django 1.5. Thanks!
comment:13 by , 12 years ago
Confirmed that the bug is fixed at bac187c0d8e829fb3ca2ca82965eabbcbcb6ddd5
. Also realized my bug is actually #20257 and not this.
Traceback