2

MongoAlchemy を使用しているときに奇妙なバグに悩まされています。

私はname = db.StringField()自分のParticipantモデルに を持っています。ほとんどの場合は問題なく動作しますが、何らかの理由でフィールドが . で上書きされることがありQueryFieldます。モジュールからクラスを再ロードParticipantすると、しばらくは正常に動作しますが、再び壊れます。

これが発生した端末セッションを次に示します。

In [99]: from webapp.models import *

In [100]: Participant.by_name('yaronTesting') # My own method, which filters by name
Out[100]: <Participant yaronTesting>

In [101]: Participant.query.all()
Out[101]: [<Participant name>, <Participant name>]

# What?

In [102]: Participant.query.all()[0]
Out[102]: <Participant name>

In [103]: Participant.query.all()[0].name
Out[103]: QueryField(name)

In [104]: from webapp.models import Participant

In [105]: Participant.query.all()
Out[105]: [<Participant yaronTesting>, <Participant tsviki>]

In [106]: Participant.query.all()[0].name
Out[106]: u'yaronTesting'

私は MongoDB を初めて使用し、これを本番環境に導入することに非常に神経質になっています。舞台裏で何が起こっているのか知っている人はいますか?

ジェフのコメントに応えて、クエリの外で問題が発生する別のセッションがあります。

In [168]: tsviki_old
Out[168]: <Participant name>

In [169]: tsviki_old.mongo_id
Out[169]: ObjectId('53f4f27a6c4dae23aba41419')

In [170]: tsviki_new = Participant.by_name('tsviki')
Out[170]: <Participant tsviki>

In [171]: tsviki_new.mongo_id
Out[171]: ObjectId('53f4f27a6c4dae23aba41419')

In [172]: tsviki_old.mongo_id
Out[172]: ObjectId('53f4f27a6c4dae23aba41419')

In [173]: tsviki_old
Out[173]: <Participant name>

In [174]: tsviki_new
Out[174]: <Participant tsviki>

In [175]: tsviki_old.name
Out[175]: QueryField(name)

In [176]: tsviki_new.name
Out[176]: u'tsviki'

In [179]: tsviki_old.created
Out[179]: QueryField(created)

In [180]: tsviki_old.modified
Out[180]: QueryField(modified)

In [181]: tsviki_old.sessions
Out[181]: QueryField(sessions)

# It happened again! To tsviki_new!

In [182]: tsviki_new.created
Out[182]: QueryField(created)

In [183]: tsviki_new
Out[183]: <Participant name>

In [184]: tsviki_new.name
Out[184]: QueryField(name)

In [185]: tsviki_new.mongo_id
Out[185]: ObjectId('53f4f27a6c4dae23aba41419')

この最後のセッションに取り組んでいる間、ある時点でファイルを保存したことを除いて、他に何もしたことを覚えていません。時間に関連する要素があるようです。通常、インタプリタをしばらく離れて戻ってきた場合に発生しますが、これを引き起こしたと特定できる特定の動作はありません。

また、参考までに:

@classmethod
def by_name(cls, name):
    return Participant.query.filter({'name': name}).first()

最後にname、関数にフィールドを追加して__init__いくつかのオブジェクトをインスタンス化しようとすると、次のエラーが発生します (以前のバージョンでは init に引数が渡されませんでした)。

In [36]: Participant.query.all()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-36-310f11265a76> in <module>()
----> 1 Participant.query.all()

/Users/kronosapiens/Dropbox/Documents/Development/code/environments/pm/lib/python2.7/site-packages/mongoalchemy/query.pyc in all(self)
    177     def all(self):
    178         ''' Return all of the results of a query in a list'''
--> 179         return [obj for obj in iter(self)]
    180 
    181     def distinct(self, key):

/Users/kronosapiens/Dropbox/Documents/Development/code/environments/pm/lib/python2.7/site-packages/mongoalchemy/query.pyc in next(self)
    410 
    411     def next(self):
--> 412         return self._next_internal()
    413     __next__ = next
    414 

/Users/kronosapiens/Dropbox/Documents/Development/code/environments/pm/lib/python2.7/site-packages/mongoalchemy/query.pyc in _next_internal(self)
    421             if obj:
    422                 return obj
--> 423             value = self.session._unwrap(self.type, value, fields=self.fields)
    424             if not isinstance(value, dict):
    425                 self.session.cache_write(value)

/Users/kronosapiens/Dropbox/Documents/Development/code/environments/pm/lib/python2.7/site-packages/mongoalchemy/session.pyc in _unwrap(self, type, obj, **kwargs)
    333     def _unwrap(self, type, obj, **kwargs):
    334         obj = type.transform_incoming(obj, session=self)
--> 335         return type.unwrap(obj, session=self, **kwargs)
    336 
    337     @property

/Users/kronosapiens/Dropbox/Documents/Development/code/environments/pm/lib/python2.7/site-packages/mongoalchemy/document.pyc in unwrap(cls, obj, fields, session)
    494         if fields is not None:
    495             params['retrieved_fields'] = fields
--> 496         obj = cls(loading_from_db=True, **params)
    497         obj._mark_clean()
    498         obj._session = session

/Users/kronosapiens/Dropbox/Documents/Development/code/jobs/paragon/webapp/webapp/models.py in __init__(self, name, **kwargs)
    319 
    320     def __init__(self, name, **kwargs):
--> 321         super(Participant, self).__init__(
    322             name=name,
    323             **kwargs)

TypeError: super(type, obj): obj must be an instance or subtype of type
4

1 に答える 1

0

MongoAlchemy の作者はこちら。他の誰かが書いたので、私はフラスコの統合にあまり精通していませんが、ここで起こっているに違いないのは、 all() がデータベースデータから作成されたインスタンスではなく、クラスParticipant のインスタンスを返しているということです。

完全に実行可能な例を提供できる場合は、詳細を説明できますが、記載されているように、質問から収集できるのはそれだけです。

于 2014-08-21T11:56:43.033 に答える