非同期Python 3.5およびMongodb



これは、 tornado



使用されるmongodb



の非同期ドライバーの主要な革新に関する記事のかなり無料の翻訳です。
この翻訳を書く主な動機は、 asyncio



async



await



およびPython 3.5



サポートなど、このバージョンで登場した革新です。
この記事自体はイノベーションのリストではなく、 MongoDB



での非同期作業の簡潔な例です。






はじめに

非同期

集約する

Python 3.5

非同期および待機





はじめに



最近、 Mongodb



Motor



用のPython



ドライバーの新しいBeta



版が公開されました。 このバージョンには、最大のアップデートの1つが含まれています。 インストールには、次を使用できます。

python -m pip install --pre motor==0.5b0







Motor 0.5



はまだPyMongo 2.8.0



依存しています。 これはPyMongo



古いバージョンですが、今回のリリースは非常に大きいため、3番目のバージョンに完全に切り替えるのに十分な時間はありませんでした。



非同期



Motor



は、 Tornado



代替としてasyncio



と統合できるようにasyncio



ました。 Remy Jolin、Andrei Svetlov svetlov 、Nikolay Novikにasyncioでの作業のためのMotor



の統合に多大な貢献をしてasyncio



ます。



Tornado



asyncio



asyncio



は関連しています。 Tornado



Motor



例:

 # Tornado API from tornado import gen, ioloop from motor.motor_tornado import MotorClient @gen.coroutine def f(): result = yield client.db.collection.insert({'_id': 1}) print(result) client = MotorClient() ioloop.IOLoop.current().run_sync(f)
      
      





そして、これがasyncioの例​​です:

 import asyncio from motor.motor_asyncio import AsyncIOMotorClient @asyncio.coroutine def f(): result = yield from client.db.collection.insert({'_id': 1}) print(result) client = AsyncIOMotorClient() asyncio.get_event_loop().run_until_complete(f())
      
      





Tornado



とは異なり、 asyncio



http



実装が含まれておらず、さらにフレームワークではありません。 これを行うには、Andrei Svetlovのaiohttp



ライブラリを使用します。 Motorがaiohttpで動作する小さな



集約する



MotorCollection.aggregateはデフォルトでカーソルを返し、カーソルはyield



なしで直接戻ります。 古い構文はサポートされなくなりました:

 # Motor 0.4 and older, no longer supported. cursor = yield collection.aggregate(pipeline, cursor={}) while (yield cursor.fetch_next): doc = cursor.next_object() print(doc)
      
      





Motor 0.5



ようにします。

 # Motor 0.5: no "cursor={}", no "yield". cursor = collection.aggregate(pipeline) while (yield cursor.fetch_next): doc = cursor.next_object() print(doc)
      
      





asyncio



はこれにyield from



を使用します。

 # Motor 0.5 with asyncio. cursor = collection.aggregate(pipeline) while (yield from cursor.fetch_next): doc = cursor.next_object() print(doc)
      
      





Python 3.5



Motor



は現在、 Python 3.5



と互換性があり、多少の労力が必要です。 Motor



はコルーチンで動作するだけでなく、 MotorClient.openMotorGridFS.putなどの機能の一部を内部的に使用してコルーチンを使用するため、これは困難でした

Python 2.6



Python 3.4



で動作するコルーチンを記述する方法がありましたが、 Python 3.5



では最終的に壊れました。 Python 3.5



ネイティブコルーチンまたはPython 2



コルーチンベースのジェネレーターに値を返す単一の方法はないため、値を返すすべての内部motor



コルーチンはコールバックを使用して書き換えられています。



非同期および待機



Python 3.5



との統合に費やされた努力に対する報酬は、 async



およびawait



構文で記述されたネイティブコルーチンでmotor



動作するようになったことです。

 async def f(): await collection.insert({'_id': 1})
      
      





MotorCollection.findMotorCollection.aggregate 、またはMotorGridFS.findのカーソルは、 次の async for



してネイティブコルーチンに美しく、非常に効率的に統合できます。

 async def f(): async for doc in collection.find(): print(doc)
      
      





どのくらい効果的ですか? 10,000ドキュメントのコレクションの場合、このコード例は0.14秒で実行されました。

 # Motor 0.5 with Tornado. @gen.coroutine def f(): cursor = collection.find() while (yield cursor.fetch_next): doc = cursor.next_object() print(doc)
      
      







gen.coroutine



yield



async



await



に単純にgen.coroutine



次のコードは、同様のことを行います。

 # Motor 0.5 with Tornado, using async and await. async def f(): cursor = collection.find() while (await cursor.fetch_next): doc = cursor.next_object() print(doc)
      
      





ただし、 async for



では0.04秒かかり、3倍高速です。

 # Motor 0.5 with Tornado, using async for. async def f(): cursor = collection.find() async for doc in cursor: print(doc)
      
      





ただし、to_listのMotorCursorは依然として大きな役割を果たします。

 # Motor 0.5 with Tornado, using to_list. async def f(): cursor = collection.find() docs = await cursor.to_list(length=100) while docs: for doc in docs: print(doc) docs = await cursor.to_list(length=100)
      
      





to_list



た関数は非同期の2倍の速度ですが、見た目はそれほど美しくなく、チャンクのサイズを指定する必要があります。 async for



は非常にスタイリッシュasync for



見え、ほとんどの場合に使用できるほど高速に動作すると思います。



motor



リリースのベータ版は常に公開されていませんでしたが、今回は別の方法で公開されました。 motor



へのasyncio



の統合は、まったく新しいものです。 また、 motor



コアの広範なリファクタリングと既存のtornado



統合の書き直しが必要だったため、すべての欠落を修正するためにベータ版がリリースされました。



PS PMに書き込むための文法エラーと翻訳エラーのリクエスト。



All Articles