2012-05-04 33 views
9

Tengo un campo JSON en mi base de datos que es comocómo escribir una consulta para obtener encontrar valor en un campo JSON en Django

jsonfield = {'username':'chingo','reputation':'5'} 

¿Cómo puedo escribir una consulta para que yo pueda encontrar si un usuario nombre existe algo así como

username = 'chingo' 
query = User.objects.get(jsonfield['username']=username) 

Sé que la consulta anterior es incorrecta, pero quería saber si hay una forma de acceder a ella?

Respuesta

9

Este uso es algo anti-patrón. Además, su implementación no va a tener un rendimiento regular, y quizás es propenso a errores.
Normalmente no use jsonfield cuando necesite buscar campos. Use la forma en que proporciona RDBMS o MongoDB (que opera internamente en BSON más rápido), como señaló Daniel.

Debido a la deterministic of JSON format, que podría lograr mediante el uso de contains (regex tiene problema cuando se trata w/múltiples '\' e incluso más lento), no creo que es bueno utilizar username de esta manera, por lo que su uso name lugar:

def make_cond(name, value): 
    from django.utils import simplejson 
    cond = simplejson.dumps({name:value})[1:-1] # remove '{' and '}' 
    return ' ' + cond # avoid '\"' 

User.objects.get(jsonfield__contains=make_cond(name, value)) 

funciona siempre y cuando

  • la jsonfield usando la misma aplicación volcado (la simplejson aquí)
  • name y value no son demasiado especial (no sé cualquier borde de esto de los casos hasta el momento, tal vez alguien podría señalarlo)
  • sus datos jsonfield no es corrupta (aunque poco probable)

en realidad, yo estoy trabajando en un jsonfield editable y pensando en la posibilidad de apoyar este tipo de operaciones. La prueba negativa es como se dijo anteriormente, se siente como magia negra, bueno.

+0

Use '' json' importación y json.dumps (... '' la simplejson' está en desuso Por cierto esto no va a trabajar en la versión anterior de Postgres – andi

1

No puede hacer eso. Use campos de base de datos normales para datos estructurados, no blobs JSON.

Si necesita buscar datos JSON, considere utilizar una base de datos noSQL como MongoDB.

15

Si está utilizando el paquete django-jsonfield, entonces esto es simple. Digamos que tiene un modelo como este:

from jsonfield import JSONField 
class User(models.Model): 
    jsonfield = JSONField() 

continuación para buscar registros con un nombre de usuario específico, sólo puede hacer esto:

User.objects.get(jsonfield__contains={'username':username}) 
+1

aparentemente! no funciona con el último (1.0.3) jsonfield. –

+0

Entonces, ¿cuál es la solución? Estoy usando 1.0.3 @ VladE.Borovtsov –

+0

Hmm, recuerdo que encontré una solución incorrecta. Pero finalmente dejé de usar este campo. campo en postgres hace mucho tiempo. @ShashankHegde –

1

Si utiliza PostgreSQL puede utilizar SQL prima hasta resolver el problema.

username = 'chingo' 
SQL_QUERY = "SELECT true FROM you_table WHERE jsonfield::json->>'username' = '%s'" 
User.objects.extra(where=[SQL_EXCLUDE % username]).get() 

donde you_table es el nombre de la tabla en su base de datos.

Cualquier método cuando trabaje con JSON como en texto sin formato, con un aspecto muy malo. Entonces, también creo que necesita un mejor esquema de base de datos.

1

Aquí es la manera que he encontrado que va a resolver su problema:

search_filter = '"username":{0}'.format(username) 
query = User.objects.get(jsonfield__contains=search_filter) 

Espero que esto ayude.

2

Desde Django 1.9, ha podido utilizar el JSONField nativo de PostgreSQL. Esto hace que la búsqueda JSON sea muy simple. En su ejemplo, esta consulta funcionaría:

User.objects.get(jsonfield__username='chingo') 

Si tiene una versión anterior de Django, o estás usando la biblioteca Django JSONField para la compatibilidad con MySQL o algo similar, aún puede realizar la consulta.

En esta última situación, jsonfield se almacenará como un campo de texto y se mapeará a un dict cuando se traiga a Django. En la base de datos, los datos se almacenarán como esto

{"username":"chingo","reputation":"5"} 

Por lo tanto, sólo tiene que buscar en el texto. Su consulta en este siutation sería:.

User.objects.get(jsonfield__contains='"username":"chingo"') 
Cuestiones relacionadas