2016-06-16 8 views
1

HaystackでWhooshを使用していて、すべて正常に動作しますが、ElasticSearchに変更したいのですが、rebuild_indexを実行すると次のエラーが発生します。私はなぜエラーが起きているのか分かりませんが、私のモデルとデータについて不平を言っているようですが、Wh​​ooshの検索/索引付けをすべてうまくいけばいいです。ここでSerializationError Elastic Searchの再構築Django App

Django==1.8.4 
elasticsearch==2.3.0 
django-haystack==2.4.1 

File "C:\Users\user.virtualenvs\pguider\lib\site-packages\elasticsearch\serializer.py", line 50, in dumps raise SerializationError(data, e) elasticsearch.exceptions.SerializationError: ({u'django_id': u'1', 'created': '2016-02-13T22:19:28.037000+00:00', 'suppl ier_code': u'BL32291', 'related_supplier_parts': [], u'django_ct': u'products.supplierpart', 'supplier': u'Parts Town', 'text': u'BL32291\n32291\nBlodgett\n\nParts Town\n\n\n', 'part_code': u'32291', u'id': u'products.supplierpart.1'}, Type Error("Unable to serialize [] (type:)",))

私のモデルです:

from django.db import models 


class Supplier(models.Model): 
    name = models.CharField(max_length=50) 

    def __unicode__(self): 
     return u'%s' % self.name 


class Part(models.Model): 
    name = models.CharField(max_length=200, null=True) 
    code = models.CharField(max_length=30, null=True) 

    def __unicode__(self): 
     return u'%s %s' % (self.code, self.name) 


class SupplierPart(models.Model): 
    part = models.ForeignKey(Part) 

    supplier = models.ForeignKey(Supplier) 
    supplier_code = models.CharField(max_length=30) 

    description = models.CharField(max_length=200) 
    price = models.CharField(max_length=6, null=True) 
    sale_price = models.CharField(max_length=6, null=True) 

    quantity = models.IntegerField(null=True) 
    photo = models.ImageField(upload_to='products', null=True) 
    url = models.URLField() 

    created = models.DateTimeField(auto_now_add=True) 

    def __unicode__(self): 
     return self.supplier_code 

    @property 
    def related_supplier_parts(self): 
     return self.part.supplierpart_set.all().exclude(pk=self.pk) 
+0

elasticsearchは 'related_supplier_parts'のリストフィールドをシリアル化できません。あなたはそれが書かれていることを教えていただけますか? –

+0

@BartoszDabrowskiは私の外部キーフィールドについて不平を言っているようですね?モデルを含めるように質問を更新しました –

答えて

1

問題があなたの財産related_supplier_partsに産みます。弾性検索はそれをシリアル化できません。このプロパティはクエリーセットを返します。

>>> parts = Part.objects.all() 
>>> import json 
>>> json.dumps({'related_supplier_parts': parts}) 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
    File "/usr/lib/python2.7/json/__init__.py", line 243, in dumps 
    return _default_encoder.encode(obj) 
    File "/usr/lib/python2.7/json/encoder.py", line 207, in encode 
    chunks = self.iterencode(o, _one_shot=True) 
    File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode 
    return _iterencode(o, 0) 
    File "/usr/lib/python2.7/json/encoder.py", line 184, in default 
    raise TypeError(repr(o) + " is not JSON serializable") 
TypeError: [] is not JSON serializable 

どのように解決するのですか?

どのプロジェクトでも、プロパティを使用してモデルを複雑化しないことがベストです。我々は広く使用されており、簡単に書くことができます。私はDjangoのキャリアで一度も財産を使用していません。私の現在のプロジェクトでは、私は153のモデルを持っています。単純な方法get_related_supplier_partsは同じ仕事をしなければならないので、99%のケースではあなたはそれらを必要としません。あなたは、オブジェクトの追加のクエリが実行されるシリアル化し、それらの何百万人をシリアル化について考えてみるたび@propertyの

class SupplierPart(models.Model): 
    [...] 

    created = models.DateTimeField(auto_now_add=True) 

    def __unicode__(self): 
     return self.supplier_code 

    def get_related_supplier_parts(self): 
     return self.part.supplierpart_set.all().exclude(pk=self.pk) 

もう一つの欠点があります。あなたは方法でそれを心配する必要はありません。

何らかの理由でこれを拒否した場合は、このクエリをリストに変換する方法を見つける必要があります。おそらくあなたのインデックスクラスで新しいフィールドを定義しています:

class MyIndex(indexes.SearchIndex, indexes.Indexable): 
    [...] 
    related_supplier_parts = indexes.MultiValueField() 

    def prepare_related_supplier_parts(self, obj): 
     return [part.id for part in obj.related_supplier_parts] 
+0

こんにちは@Bartosz詳細な説明をありがとうございます。私は実際には、search_index.pyファイルをreturn obj.related_supplier_partsから変更することで、これを処理することができました。 obj.related_supplier_partsの一部のstr(part)を返します。 –

関連する問題