#13252 closed New feature (fixed)
Use the natural key instead of the primary key when serializing
| Reported by: | Chris Beaven | Owned by: | Malcolm Tredinnick |
|---|---|---|---|
| Component: | Core (Serialization) | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Tai Lee, chris@…, Chris Spencer, dev@…, charette.s@… | Triage Stage: | Accepted |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | yes |
| Easy pickings: | no | UI/UX: | no |
Description
This would allow existing objects to be updated and missing objects to be added across databases (e.g. when the autonumber primary keys may not match).
Attachments (7)
Change History (36)
by , 16 years ago
| Attachment: | 13252.diff added |
|---|
comment:1 by , 16 years ago
| Has patch: | set |
|---|---|
| Needs documentation: | set |
| Needs tests: | set |
comment:2 by , 16 years ago
| Patch needs improvement: | set |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
I accept the use case - that you should be able to say "update the existing object that matches the natural key, or create a new object if one doesn't exist". However I'm not convinced that providing a natural key for the PK value is the right way to do this.
Essentially, this approach means specifying the natural key data twice - once in the fields of the object, and once in the primary key value. This strikes me as especially un-DRY.
I haven't given this a lot of thought, but there might be a way of using the natural key without to specify it in the pk attribute. A natural key needs to be unique, so if a model defines a natural key, you shouldn't need to have the PK value specifically (or the natural key value as the primary key) in order to reconstruct the natural key for an object. This does leave the question of when the 'update or create' behavior should be invoked, but I think this will be less prone to error than reproducing the natural key.
by , 16 years ago
| Attachment: | 13252.2.diff added |
|---|
comment:3 by , 15 years ago
| Patch needs improvement: | unset |
|---|
comment:4 by , 15 years ago
| Needs documentation: | unset |
|---|---|
| Needs tests: | unset |
comment:5 by , 15 years ago
| Owner: | changed from to |
|---|
comment:7 by , 15 years ago
| Cc: | added |
|---|
by , 15 years ago
| Attachment: | 13252-natural-key-serializing-r14992.diff added |
|---|
comment:8 by , 15 years ago
Updated patch to work on r14992. Appears to work well locally. serializers_regress tests pass (on sqlite at least).
by , 15 years ago
| Attachment: | 13252-natural-key-serializing-r14995.diff added |
|---|
comment:11 by , 15 years ago
I've just updated the patch after feedback from freakboy3742 on IRC.
The new patch adds --natural-foreign and --natural-primary options to the dumpdata management command, maps the -n and --natural options to --natural-foreign and adds a note in the documentation that the old options are deprecated. This should retain backwards compatibility with anyone who was depending on data dumped with natural keys still containing a pk field for models that support natural keys. It also adds the corresponding use_natural_foreign_keys and use_natural_primary_keys arguments to serializers.serialize() and maps use_natural_keys to use_natural_foreign_keys.
I've left a comment in the source code where I think we should probably raise a deprecation warning (but not actually raised it) if that ends up being the desired behaviour.
One quirk is that the code beginning at line 30 in django/core/serializers/python.py appears to affect the order of fields in serialized output depending on how the data dict is constructed, even though the resulting data dict contains the same data. If I first create the data dict with model and fields items and then conditionally add a pk item (as the old patch did), then the serialized output is different to when I create the data dict with model, pk and fields items. Rather than change a tonne of hard coded tests, I construct the data dict the same way that it would have been before the patch which results in a couple of duplicated lines of code.
comment:12 by , 15 years ago
| Type: | → New feature |
|---|
comment:13 by , 15 years ago
| Severity: | → Normal |
|---|
comment:14 by , 14 years ago
| Easy pickings: | unset |
|---|---|
| Patch needs improvement: | set |
13252-natural-key-serializing-r14995.diff fails to apply cleanly on to trunk
by , 14 years ago
| Attachment: | 13252-natural-key-serializing-r16406.diff added |
|---|
Updated to apply cleanly on current trunk
comment:15 by , 14 years ago
| Patch needs improvement: | unset |
|---|---|
| UI/UX: | unset |
comment:16 by , 14 years ago
| Patch needs improvement: | set |
|---|
The new behaviour needs to be optional to be backwards compatible.
comment:17 by , 14 years ago
| Cc: | added |
|---|
comment:18 by , 14 years ago
| Cc: | added |
|---|
by , 14 years ago
| Attachment: | 13252-natural-key-serializing-r17262.diff added |
|---|
Updated to current trunk
comment:19 by , 14 years ago
| Cc: | added |
|---|
comment:20 by , 13 years ago
| Cc: | added |
|---|
comment:21 by , 13 years ago
I've updated this patch again on a branch at GitHub.
https://github.com/thirstydigital/django/tree/tickets/13252-natural-key-serializing
SmileyChris, can you elaborate on making the new behaviour optional? Unless I'm missing something, it is? The --natural option maps to --natural-foreign (which behaves the same, with a pending deprecation warning) and we now have a new --natural-primary option as well.
I believe I've incorporated all the changes russellm requested and this should be RFC now.
comment:22 by , 13 years ago
FWIW all tests pass on python 2.7.3rc1 sqlite3. I guess the backward compatibility or must opt-in issue SmileyChris was referring to is no more with two new flags?
comment:23 by , 13 years ago
I would be very pleased to see this feature enhancement reach the master branch asap 'cause I actually pretty much need it and have write myself some kind of the same..
comment:25 by , 13 years ago
| Status: | reopened → new |
|---|
comment:26 by , 12 years ago
| Patch needs improvement: | unset |
|---|
Rebased onto master and changes for feedback integrated.
comment:28 by , 12 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
This also fixes #11486 by proxy.