Opened 16 years ago
Closed 10 years ago
#12685 closed New feature (fixed)
Serialized objects' save function does not respect force_insert
| Reported by: | dcotruta | Owned by: | |
|---|---|---|---|
| Component: | Core (Serialization) | Version: | 1.1 |
| Severity: | Normal | Keywords: | save, force_insert, force_update |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Given a serialized trivial object, of the type models.Model, which does not override any functions, a deserialized object does not accept the force_insert keyword argument for its save function.
class XYZ(models.Model):
xyz_creation_date = models.DateTimeField(verbose_name=_("Date Opened"),
blank=False,
auto_now_add=True,
editable=False
)
xyz_is_open = models.BooleanField(default=True)
xyz_last_updated = models.DateTimeField(verbose_name=_("Last Report"),
blank=False,
auto_now=True
)
xyz_synced = models.BooleanField(default=False)
If this model exists on two separate servers, and instances of this object are serialized, passed over the wire, and then deserialized, the save function on the receiving server cannot pass force_insert=True - doing so yields "save() got an unexpected keyword argument 'force_insert'".
Any ideas?
Change History (20)
comment:1 by , 16 years ago
| Description: | modified (diff) |
|---|---|
| Resolution: | → invalid |
| Status: | new → closed |
comment:2 by , 16 years ago
| Resolution: | invalid |
|---|---|
| Status: | closed → reopened |
Erm, I'm not asking a question, I'm stating a fact.
http://docs.djangoproject.com/en/dev/ref/models/instances/#saving-objects states very clearly the function signature as:
Model.save([force_insert=False, force_update=False, using=DEFAULT_DB_ALIAS])
Deserialized objects of the type I've described above, which DO NOT override the save behavior, don't accept the force_insert keyword argument. This is not a question - it's a bug.
Unless I'm missing something, there should be no difference in the behavior of save for deserialized objects.
follow-up: 8 comment:3 by , 16 years ago
| Has patch: | set |
|---|---|
| Needs tests: | set |
The problem is that the call to save_base in core/serializers/base.py within the class DeserializedObject does not have the capability to carry through the correct signature.
It's simple to fix:
class DeserializedObject(object):[[BR]]
...
def save(self, save_m2m=True, force_insert=False, force_update=False):
# Call save on the Model baseclass directly. This bypasses any
# model-defined save. The save is also forced to be raw.
# This ensures that the data that is deserialized is literally
# what came from the file, not post-processed by pre_save/save
# methods.
# dcotruta - changed signature to handle force_insert and force_update
models.Model.save_base(self.object, raw=True, force_insert=force_insert, force_update=force_update)
...
I'll provide a patch tonight, when I get round to it.
russellm - next time actually read the problem - I'm not trying to be rude, but this kind of attitude is not helpful in open source!
comment:4 by , 16 years ago
| Has patch: | unset |
|---|
comment:5 by , 16 years ago
| Component: | Database layer (models, ORM) → Serialization |
|---|---|
| milestone: | → 1.2 |
Fixed component to show this is a serialization, not models, bug.
comment:6 by , 16 years ago
| Keywords: | save force_insert force_update added |
|---|
comment:7 by , 16 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
follow-up: 9 comment:8 by , 16 years ago
| Triage Stage: | Accepted → Unreviewed |
|---|
Replying to dcotruta:
The problem is that the call to save_base in core/serializers/base.py within the class DeserializedObject does not have the capability to carry through the correct signature.
Exactly, and this (the existence of DeserializedObject, the fact that its save method isn't the same as the Model save method, and that you need to provide your own logic to decide if a DeserializedObject instance should be saved or not) is intended and documented (in the documentation that should be read in first place: The one about (de)serializing) behavior:
http://docs.djangoproject.com/en/1.1/topics/serialization/#deserializing-data
comment:9 by , 16 years ago
I do see what you're trying to say, but you must admit that in many cases serialization is used to carry out trivial synchronization. In those cases, it makes sense to be able to implement the normal save behavior - indeed it would be doubly useful to be able to use new attributes like force_insert since they would throw pk errors "for free" - a very easy way of preventing data overwrites.
Just because you can create your own save function doesn't mean the built in one should fail to support standard attributes available everywhere else.
I'm not submitting this bug just for the fun of it, but because force_insert is a rather unusual call which happens to be very useful when handling over-the-wire object movement.
comment:10 by , 16 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
comment:11 by , 16 years ago
| milestone: | 1.2 |
|---|
1.2 is feature-frozen, moving this feature request off the milestone.
comment:12 by , 15 years ago
| Severity: | → Normal |
|---|---|
| Type: | → New feature |
comment:15 by , 13 years ago
| Status: | reopened → new |
|---|
comment:16 by , 10 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:17 by , 10 years ago
Added test case and fix here: https://github.com/django/django/pull/4811
comment:18 by , 10 years ago
| Has patch: | set |
|---|---|
| Needs tests: | unset |
comment:19 by , 10 years ago
| Owner: | removed |
|---|---|
| Status: | assigned → new |
Trac is not for asking how-to questions. If you want to know how to do something, ask on django-users.