#30711: Document django.contrib.postgres.fields.hstore.KeyTransform.
--------------------------------------+------------------------------------
     Reporter:  Gustav Eiman          |                    Owner:  nobody
         Type:  Cleanup/optimization  |                   Status:  new
    Component:  Documentation         |                  Version:  master
     Severity:  Normal                |               Resolution:
     Keywords:  HStoreField F         |             Triage Stage:  Accepted
    Has patch:  0                     |      Needs documentation:  0
  Needs tests:  0                     |  Patch needs improvement:  0
Easy pickings:  0                     |                    UI/UX:  0
--------------------------------------+------------------------------------
Changes (by felixxm):

 * component:  contrib.postgres => Documentation
 * owner:  (none) => nobody
 * type:  New feature => Cleanup/optimization
 * stage:  Unreviewed => Accepted


Old description:

> When using F objects for key lookups on HStoreFields it never digs down
> to get the keys but unexpectedly returns the entire object.
>
> Lets say we have this model:
> {{{
> from django.contrib.postgres.fields import HStoreField
> from django.db import models
>
> class Person(models.Model):
>     name = models.CharField(max_length=256)
>     attributes = HStoreField()
> }}}
>
> We then populate it.
> {{{
> Person.objects.create(name="James", attributes={"age": "30", "height":
> "190"})
> }}}
>
> Here comes the thing that bothers me. If we try to access either of these
> keys the entire attributes cell will be returned.
> {{{
> p = Person.objects.annotate(length=F("attributes__height"))
> p[0].height
> >>> {"age": "30", "height": "190"}
> }}}
>
> While the expected result would be an error or the value of the height
> field, it's not.
>
> I propose either making F objects support these fields or creating a new
> type to handle this, a workaround that I'm playing around with myself.
>
> {{{
> from django.contrib.postgres.fields.jsonb import KeyTransformFactory
>
> class HStoreF(F):
>     def resolve_expression(self, query=None, allow_joins=True,
> reuse=None, summarize=False, for_save=False):
>         rhs = super().resolve_expression(query, allow_joins, reuse,
> summarize, for_save)
>         field_list = self.name.split("__")
>         if field_list[-1] == rhs.target.name:
>             raise LookupError(
>             "HStoreF requires a key lookup in order to avoid unexpected
> behavior. "
>             "Please append '__somekey' to '{}'."
>             .format("__".join(field_list)))
>         return KeyTransformFactory(field_list[-1])(rhs)
>
> }}}
>
> An issue with this is that updating models with it still wont work. As an
> error is raised in {{{Query.resolve_ref()}}} due to the fact that it
> interprets the {{{"__"}}} as an attempted join. This could be solved by
> using a different lookup separator for keys (maybe relevant for JSONField
> to?), but I was unable to successfully implement this.
>
> Similar issue with JSONField: https://code.djangoproject.com/ticket/29769

New description:

 Document `django.contrib.postgres.fields.hstore.KeyTransform` in the
 [https://docs.djangoproject.com/en/dev/ref/contrib/postgres/fields/#hstorefield
 HStoreField documentation] that can be used on the right hand side of a
 filter or an annotation.

--

Comment:

 I changed ticket description, thanks!

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30711#comment:3>
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 django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/066.c6d1ede2f09c230fca38b38c2c105102%40djangoproject.com.

Reply via email to