#26511: Django 1.9 and Postgres 9.4 jsonb string containment inside JSONField
----------------------------------+-----------------------------
     Reporter:  eoinmurray        |      Owner:
         Type:  Bug               |     Status:  new
    Component:  contrib.postgres  |    Version:  1.9
     Severity:  Normal            |   Keywords:  postgres, jsonb
 Triage Stage:  Unreviewed        |  Has patch:  0
Easy pickings:  0                 |      UI/UX:  0
----------------------------------+-----------------------------
 I have a model called File with a JSONField. I create a new file and
 inside the JSONField is a key value pair

 {{{
 {"title": "the cow jumped over the moon"}
 }}}

 I want to be able to search for objects where the title contains moon...

 I can do it will the following raw SQL statement in Django


 {{{
 File.objects.raw('SELECT * FROM web_file WHERE (metadata ->> %s)::text
 LIKE %s;', ['title', '%moon%'])[0]
 }}}


 This works, but doesn't return a queryset, and doesn't play nice with the
 rest of my code. I was hoping I could do this query with the Django ORM.
 From the docs, I thought the following code would work:


 {{{
 File.objects.filter(metadata__title__contains='moon')
 }}}


 But gives the an error (traceback here
 https://gist.github.com/eoinmurray/04843b77e8d71fad8cfa4a990c00740a)


 {{{
 DataError: invalid input syntax for type json
 LINE 1: ...b_file" WHERE "web_file"."metadata" -> 'title' @> 'moon' ORD...

 DETAIL:  Token "moon" is invalid.
 CONTEXT:  JSON data, line 1: moon

 }}}

 Perhaps this is something that cannot be accomplished with the ORM, and
 therefore is not a bug - but I'm not really sure from the documentation...


 Here is all the code needed to recreate the error, Im using Django 1.9,
 Postgres 9.4 and psycopg2 2.6.1.

 models.py


 {{{
 from django.db import models
 from django.contrib.postgres.fields import JSONField

 class File(models.Model):
     owner = models.ForeignKey('auth.User', related_name='file_user')
     created_on = models.DateTimeField(auto_now_add=True, blank=True)
     name = models.CharField(max_length=100)
     metadata = JSONField(null=True, blank=True, default=dict())

 }}}

 query.py


 {{{
 from web.models import File
 from django.contrib.auth.models import User

 user = User.objects.get(pk=1)

 File.objects.create(name="testfile.txt", owner=user, metadata={'title':
 'the cow jumped over the moon'})

 # raw query that works
 # File.objects.raw('SELECT * FROM web_file WHERE (metadata ->> %s)::text
 LIKE %s;', ['title', '%moon%'])[0]

 File.objects.filter(metadata__title__contains='moon')

 >>> outputs traceback
 https://gist.github.com/eoinmurray/04843b77e8d71fad8cfa4a990c00740a
 >>> DataError: invalid input syntax for type json
 >>> LINE 1: ...b_file" WHERE "web_file"."metadata" -> 'title' @> 'moon'
 ORD...
                                                              ^
 >>> DETAIL:  Token "moon" is invalid.
 >>> CONTEXT:  JSON data, line 1: moon
 }}}

--
Ticket URL: <https://code.djangoproject.com/ticket/26511>
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 post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/053.77311ad6c64d1b3b26faff511fbebe1e%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to