非同期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.openやMotorGridFS.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.find 、 MotorCollection.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