Opened 14 years ago

Closed 14 years ago

Last modified 12 years ago

#12163 closed (fixed)

Regression: Pickling error saving session with unsaved model instances (*_Deferred_)

Reported by: Ryan Fugger Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Keywords: pickle, session, model, instance, deferred
Cc: arv@… Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When attempting to store freshly-created unsaved model instances in a session, I get the following error:

PicklingError: Can't pickle <class 'order.models.OrderItem_Deferred_'>: attribute lookup order.models.OrderItem_Deferred_ failed

The object is an instance of OrderItem. Apparently django instantiates it as !OrderItem_Deferred_, and then pickle can't deal with it?

Using svn revision 11723. Worked fine in 11616.

Attachments (2)

base.py.diff (495 bytes ) - added by Ryan Fugger 14 years ago.
Set model to _meta.proxy_for_model by default for deferred
12163_test.diff (983 bytes ) - added by Ryan Fugger 14 years ago.
Test case added to defer_regress tests.

Download all attachments as: .zip

Change History (11)

comment:1 by Russell Keith-Magee, 14 years ago

milestone: 1.2

There have been some recent changes to the infrastructure around pickling of deferred fields - evidently you have found a case that wasn't covered by our test suite.

Can you please provide a complete test case - i.e., a minimal set of models, and the exact sequence of commands that fails.

comment:2 by Ryan Fugger, 14 years ago

I'll try to work up a test case when I have time. Strangely, when I reverted to r11616, the __reduce__ function was broken (model used before assignment), even though it was definitely working fine three days ago. So maybe I'm doing something wrong, although I don't think my surrounding code has changed since then.

In the meantime, replacing model = self.__class__ with model = self._meta.proxy_for_model near the start of db.models.base.Model.__reduce__ seems to fix the issue for me. I'm not sure if this is a good general solution or not, because I don't really know how deferred fields work.

by Ryan Fugger, 14 years ago

Attachment: base.py.diff added

Set model to _meta.proxy_for_model by default for deferred

comment:3 by Ryan Fugger, 14 years ago

(Sorry, probably better not to replace model = self.__class__, but just to set model = self._meta.proxy_for_model as a default when self._deferred is True.

comment:4 by Ryan Fugger, 14 years ago

Cc: arv@… added

by Ryan Fugger, 14 years ago

Attachment: 12163_test.diff added

Test case added to defer_regress tests.

comment:5 by AndrewIngram, 14 years ago

I'd just like to add that it's revision 11691 that causes this, using 11690 should fix things for now.

comment:6 by Ryan Fugger, 14 years ago

Thanks Andrew. r11690 does work. I hadn't cleared out my session last time I tried a pre-11691 revision, so pickled *_Deferred_ objects were still hanging around and causing errors.

comment:7 by Russell Keith-Magee, 14 years ago

Resolution: fixed
Status: newclosed

(In [11732]) Fixed #12163 -- Corrected the unpickling of non-deferred models. Thanks to rfugger for the report and test case.

comment:8 by Russell Keith-Magee, 14 years ago

(In [11733]) [1.1.X] Fixed #12163 -- Corrected the unpickling of non-deferred models. Thanks to rfugger for the report and test case.

Backport of r11732 from trunk.

comment:9 by Jacob, 12 years ago

milestone: 1.2

Milestone 1.2 deleted

Note: See TracTickets for help on using tickets.
Back to Top