#32491: Updating a field based on a JSONField's sub-value adds extra quotes
[postgres]
-------------------------------------+-------------------------------------
     Reporter:  Baptiste Mispelon    |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  master
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

 * stage:  Unreviewed => Accepted


Comment:

 Bonjour Baptiste, always a pleasure to see you around :)

 > Initially, I thought that adding an explicit Cast (using
 update(name=Cast(F('data__name'), CharField()))) might solve the issue,
 but the test still fails in the same way.

 yeah that's expected since `::json::text` is pretty much the equivalent of
 `json.dumps` (e.g. see #27257 for a similar problem)

 > Adding to my confusion was the fact that this behavior doesn't appear
 when using annotate: annotate(dataname=F('data__name')) correctly yields
 django without the extra quotes.

 Right this happens because `JSONField.from_db_value` attempts a
 `json.loads` on the return value so `'"foo"' -> 'foo'`

 > I'm not sure if this is really a bug or how fixable it is (I don't see
 how Django could guess that it should use KeyTextTransform over
 KeyTransform) but silently adding extra " seems pretty bad. Having
 KeyTransform/KeyTextTransform documented could help, though I'm not sure
 if I would have discovered their existence even if they were.

 It could be done by having transforms used `for_save` have access to
 `output_field` of the left hand side of the `UPDATE`/`INSERT` (e.g a
 `CharField`) in this case and decide whether `->>` or `->` should be used
 but that would be slightly backward incompatible.

 An alternative could be to introduce an `__astext` lookup on `JSONField`
 that would translate to the usage of `KeyTextTransform`. That would make
 it explicit which SQL operator must be used and a similar approach could
 be used for `__asint` and `__asfloat` to
 
[https://github.com/django/django/blob/64a0d1ef6e7a6739148996e9584bbb61fe3dcc60/django/db/models/fields/json.py#L462-L533
 remove the lookups hacks for textual and numeric values] as right now it's
 not possible to go things like `jsonfield__name__gt="Simon"`

-- 
Ticket URL: <https://code.djangoproject.com/ticket/32491#comment:2>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/067.a9b1c3de5c49800b0419ea923965ccb0%40djangoproject.com.

Reply via email to