2017-01-11 27 views
0

您好我使用AsyncIOMotorClient異步數據庫調用到mongoDb。 以下是我的代碼。RuntimeError:任務附加到不同的循環

xyz.py 
async def insertMany(self,collection_name,documents_to_insert): 
    try: 
     collection=self.database[collection_name] 
     document_inserted = await collection.insert_many(documents_to_insert) 
     return document_inserted 
    except Exception: 
     raise 

def insertManyFn(self,collection_name,documents_to_insert): 
    try: 
     loop=asyncio.new_event_loop() 
     asyncio.set_event_loop(loop) 
     loop1=asyncio.get_event_loop() 
     inserted_documents_count = loop1.run_until_complete(self.insertMany(collection_name, documents_to_insert)) 
     if inserted_documents_count==len(documents_to_insert): 
      document_to_insert={Config.DB_JOB_COLUMN:Job.job_id,Config.DB_JOB_RESULT_COLUMN:Config.DB_JOB_RESULT_SUCCESS} 
      loop1.run_until_complete(self.insertOne(Config.DB_JOB_COLLECTION, document_to_insert)) 
    except Exception: 
     raise 

xyz1.py 
t=Timer(10,xyz.insertManyFn,\ 
       (collection_name,documents_to_insert)) 
t.start() 

雖然運行此我得到一個異常

RuntimeError: Task <Task pending coro=<xyz.insertMany() running at <my workspace location>/xyz.py:144> cb=[_run_until_complete_cb() at /usr/lib64/python3.5/asyncio/base_events.py:164]> got Future <Future pending cb=[_chain_future.<locals>._call_check_cancel() at /usr/lib64/python3.5/asyncio/futures.py:431]> attached to a different loop 

在上面的程序insertManyFn將被調用10秒後,做的插入操作。但是,當它第一次調用insertMany時,我得到一個異常。

回答

1

根據documentation,AsyncIOMotorClient應該通過ioloop如果你不使用默認的。嘗試創建客戶端您創建活動後循環:

loop=asyncio.new_event_loop() 
asyncio.set_event_loop(loop) 
client = AsyncIOMotorClient(io_loop=loop) 
+0

試過這樣做,但得到一個錯誤,類型錯誤:「_UnixSelectorEventLoop」對象不是可迭代 – ANegi

+0

對不起,呼叫應該是:'AsyncIOMotorClient(io_loop =循環)' – Udi

+0

再次我得到異常「任務attachted到不同的循環「 – ANegi

0

我已經修改了代碼,它的工作。

def insertManyFn(self,loop,collection_name,documents_to_insert): 
    try: 
     inserted_documents_count = loop.run_until_complete(self.insertMany(event_loop,collection_name, documents_to_insert)) 
     if len(inserted_documents_count)==len(documents_to_insert): 
      document_to_insert={Config.DB_JOB_COLUMN:Job.job_id,Config.DB_JOB_RESULT_COLUMN:Config.DB_JOB_RESULT_SUCCESS} 
      loop1.run_until_complete(self.insertOne(Config.DB_JOB_COLLECTION, document_to_insert)) 
    except Exception: 
     raise 

loop=asyncio.get_event_loop() 
t=Timer(10,self.xyz.insertManyFn,(loop,collection_name,documents_to_insert)) 
t.start() 

解釋 - 我使用python線程計時器,它創建自己的線程來執行一段時間後的函數。所以,在這個線程中,我得到的事件循環不應該是正確的方法,它應該首先獲取事件循環並在其中創建一個計時器線程。 我想這是唯一的原因。

+0

另請參閱:http://stackoverflow.com/questions/41399229/using-threading-timer-with-asycnio – Udi

+0

@Udi感謝您的幫助。我想知道一件事,我的應用程序支持異步CRUD操作,所以對於每個操作,我都得到一個事件循環。這種方法好嗎? – ANegi

+0

否 - 您的整個應用程序應該在一個事件循環內運行。 – Udi