1

次の MongonEngine モデルがあります。

from app import db
from datetime import datetime
from mongoengine import signals


class PathEmbedded(db.EmbeddedDocument):
    """
        To be embedded.
    """

    _id = db.ObjectIdField(required=False)
    distance = db.IntField(required=False, min_value=0, default=0)
    meta = {
        "allow_inheritance": True,
    }

    def __unicode__(self):
        return "Path '%s': %d m" % (self.id, self.distance)


class Path2(PathEmbedded, db.Document):
    """
        Same as above, but standalone version to be stored in its own collection.
    """

    _id = db.ObjectIdField()
    orig = db.ObjectIdField(required=True)
    dest = db.ObjectIdField(required=True)
    updateStamp = db.DateTimeField(required=True)
    ok_to_use = db.BooleanField(required=True, default=False)
    meta = {
        'indexes': [
            {
                'fields': ['ok_to_use', 'orig', 'dest'],
                'cls': False,       # does this affect performance?!
            },
        ],
    }

    @classmethod
    def pre_save(cls, sender, document, **kwargs):
        document.updateStamp = datetime.utcnow()

    def to_embedded(self):
        """
            Converts the standalone Path instance into an embeddadle PathEmbedded instance.
        """

        import json
        temp = json.loads(self.to_json())

        #remove the {"_cls": "Location"} key.
        #If we don't do this, the output will be a 'Location' instance, not a 'LocationEmbedded' instace
        temp.pop('_cls')

        return PathEmbedded().from_json(json.dumps(temp))



    def get_from_gmaps(self):
        """
            Get distance from Google maps using the directions API and append to the 'paths' list.
            Return False on error or True on success.
        """

        try:
            self.distance = 10,
            self.save()

        except Exception, e:
            print str(e)
            return False

        else:
            return True

# connect event hooks:
signals.pre_save.connect(Path2.pre_save, sender=Path2)

したがって、ある時点で、次のように呼び出してパス インスタンスを更新していますget_from_gmaps()

from app.models.Path2 import Path2 as P
from bson import ObjectId

p=P(orig=ObjectId(), dest=ObjectId())
p.save()
p.get_from_gmaps()

これは発生します:

>>> p.get_from_gmaps()
ValidationError (Path2:54d34b97362499300a6ec3be) (10 could not be converted to int: ['distance'])
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "[...]app/models/Path2/get_from_gmaps.py", line 18, in get_from_gmaps
    self.save()
  File "[...]venv/local/lib/python2.7/site-packages/mongoengine/document.py", line 224, in save
    self.validate(clean=clean)
  File "[...]venv/local/lib/python2.7/site-packages/mongoengine/base/document.py", line 323, in validate
    raise ValidationError(message, errors=errors)
ValidationError: ValidationError (Path2:54d34b97362499300a6ec3be) (10 could not be converted to int: ['distance'])

元々、私はいくつかのjsonから解析され、intに変換された整数を保存していましたが、何かが間違っていると思っていましたが、デバッグのためにint値に置き換えて、これを取得しました. どこから始めればいいのか本当にわかりませんoO

編集:完全な [非] 動作例を提供する拡張コード。

4

2 に答える 2

1

の後に余分なコンマがあります10:

self.distance = 10,
                  ^

distanceint ではなく、int を含むタプルに設定しています。


ヒント:このような役に立たないメッセージが表示される理由は、MongoEngine が%sフォーマット文字列を不適切に使用しているためです。実際、タプルは特殊なケースであるため、の結果はsomething"%s" % somethingのタイプに依存します。比較:

>>> '%s' % 10
'10'
>>> '%s' % (10,)
'10'
>>> '%s' % (10, 11)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting
>>> '%s' % ((10,),)  # This is the correct way of formatting strings
'(10,)'              # when the type of the argument is unknown.

もちろん、これは MongoEngine の問題ですが、コードで同じ種類の間違いを避けたい場合は、常に%演算子の右側でタプルを使用するか、.format()メソッドを使用することをお勧めします。

于 2015-02-05T11:14:20.043 に答える
0

selfあなたが送ったモデルは正しいものですか?

この ValidationError は、ドキュメントで ReferenceField を宣言し、参照先ドキュメントを保存する前にこのドキュメントを保存しようとするとスローされます (Mongoengine は、参照のクラスと ObjectId を含む辞書として MongoDB の参照フィールドを表します)。

于 2015-02-04T15:54:23.963 に答える