データベースに次のようなjsonフィールドがあります
jsonfield = {'username':'chingo','reputation':'5'}
ユーザー名が存在するかどうかを確認できるようにクエリを作成するにはどうすればよいですか。何かのようなもの
username = 'chingo'
query = User.objects.get(jsonfield['username']=username)
上記のクエリが間違っていることは知っていますが、それにアクセスする方法があるかどうか知りたいですか?
この使用法はややアンチパターンです。また、その実装は通常のパフォーマンスを発揮せず、おそらくはエラーが発生しやすくなります。
通常、フィールドを検索する必要がある場合は、jsonfieldを使用しないでください。 Danielが指摘したように、RDBMSが提供する方法またはMongoDB(より高速なBSONで内部的に動作する)を使用します。
JSON形式の決定論 のため、contains
を使用してそれを達成できます(regex
は複数の'\'
を処理するときに問題があり、さらに遅い)、使用するのは良いことではないと思いますusername
このように、代わりにname
を使用します。
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))
それは
simplejson
)name
およびvalue
はではありませんあまりにも特別(これまでのところegde-caseはわかりません、誰かが指摘するかもしれません)実際、私は編集可能なjsonfieldに取り組んでおり、そのような操作をサポートするかどうかを考えています。否定的な証拠は上で述べたように、それはまあ、いくつかの黒魔術のように感じます。
Django-jsonfieldパッケージを使用している場合、これは簡単です。次のようなモデルがあるとします。
from jsonfield import JSONField
class User(models.Model):
jsonfield = JSONField()
次に、特定のsernameのレコードを検索するには、次のようにします。
User.objects.get(jsonfield__contains={'username':username})
Django 1.9以降、PostgreSQLのネイティブJSONFieldを使用できるようになりました。これにより、JSONの検索が非常に簡単になります。この例では、次のクエリが機能します。
User.objects.get(jsonfield__username='chingo')
古いバージョンのDjangoを使用している場合、またはMySQLなどとの互換性のためにDjango JSONFieldライブラリを使用している場合でも、クエリを実行できます。
後者の状況では、jsonfield
はテキストフィールドとして保存され、Djangoに取り込まれるとdictにマップされます。データベースでは、データは次のように保存されます
{"username":"chingo","reputation":"5"}
したがって、テキストを簡単に検索できます。このsiutationでのクエリは次のようになります。
User.objects.get(jsonfield__contains='"username":"chingo"')
PostgreSQLを使用している場合は、rawsqlを使用して問題を解決できます。
username = 'chingo'
SQL_QUERY = "SELECT true FROM you_table WHERE jsonfield::json->>'username' = '%s'"
User.objects.extra(where=[SQL_EXCLUDE % username]).get()
どこ you_table
はデータベース内のテーブルの名前です。
プレーンテキストのようにJSONを操作する場合のメソッドは、非常に悪い方法のように見えます。ですから、データベースのより良いスキーマが必要だと思います。
これがあなたの問題を解決することを私が見つけた方法です:
search_filter = '"username":{0}'.format(username)
query = User.objects.get(jsonfield__contains=search_filter)
お役に立てれば。
2019:@freethebeesが指摘しているように、今では次のように簡単です:
User.objects.get(jsonfield__username='chingo')
ただし、ドキュメントの例で説明されているように、深くクエリを実行できます。jsonが配列の場合は、整数を使用してインデックスを作成できます。
https://docs.djangoproject.com/en/2.2/ref/contrib/postgres/fields/#querying-jsonfield
>>> Dog.objects.create(name='Rufus', data={
... 'breed': 'labrador',
... 'owner': {
... 'name': 'Bob',
... 'other_pets': [{
... 'name': 'Fishy',
... }],
... },
... })
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': None})
>>> Dog.objects.filter(data__breed='collie')
<QuerySet [<Dog: Meg>]>
>>> Dog.objects.filter(data__owner__name='Bob')
<QuerySet [<Dog: Rufus>]>
>>> Dog.objects.filter(data__owner__other_pets__0__name='Fishy')
<QuerySet [<Dog: Rufus>]>
これはpostgres用ですが、MySQLのような他のDBでも同じように機能すると思います
あなたはそれをすることはできません。 JSON BLOBではなく、構造化データに通常のデータベースフィールドを使用します。
JSONデータを検索する必要がある場合は、MongoDBなどのnoSQLデータベースの使用を検討してください。