简体   繁体   English

附加到不同循环的未来任务

[英]Future task attached to a different loop

I am trying to connect to mongodb in FastAPI.我正在尝试在 FastAPI 中连接到 mongodb。 I am repeatedly getting this exception.我反复收到此异常。

File - main.py文件 - main.py

app = FastAPI(
    title=config.PROJECT_NAME, docs_url="/api/docs", openapi_url="/api"
)

@app.get("/api/testing")
async def testit():
    user_collection = readernetwork_db.get_collection("user_collection")
    all_users = await user_collection.find_one({"email": "sample_email"})
    print("all users --- ", all_users)
    return all_users

if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", reload=True, port=8888)

File - session.py文件 - session.py

import motor.motor_asyncio
from app.core import config


print("here we go again....")
client = motor.motor_asyncio.AsyncIOMotorClient(
    config.MONGOATLAS_DATABASE_URI)
readernetwork_db = client.get_database("readernetwork")

Exception -:例外 -:

all_users = await user_collection.find_one({"email": "sample_email"})

RuntimeError: Task <Task pending name='Task-4' coro=<RequestResponseCycle.run_asgi() running at /usr/local/lib/python3.8/site-packages/uvicorn/protocols/http/h11_impl.py:389> cb=[set.discard()]> got Future <Future pending cb=[_chain_future.<locals>._call_check_cancel() at /usr/local/lib/python3.8/asyncio/futures.py:360]> attached to a different loop

I don't know where I am getting this wrong.我不知道我在哪里弄错了。 Should I specify a event loop to motor?我应该为电机指定一个事件循环吗?

You can have mongodb motor client in the global scope, but creating and closing it should be done inside an async function.您可以在全局 scope 中拥有mongodb motor客户端,但创建和关闭它应该在异步 function 中完成。 The most preferable way of doing that in startup and shutdown handler of the application.在应用程序的startupshutdown处理程序中执行此操作的最优选方式。 Like so:像这样:

# mongodb.py
from motor.motor_asyncio import AsyncIOMotorClient


db_client: AsyncIOMotorClient = None


async def get_db_client() -> AsyncIOMotorClient:
    """Return database client instance."""
    return db_client


async def connect_db():
    """Create database connection."""
    db_client = AsyncIOMotorClient(DB_URL)

async def close_db():
    """Close database connection."""
    db_client.close()
# main.py
app = FastAPI(title=PROJECT_NAME)
...
app.add_event_handler("startup", connect_db)
app.add_event_handler("shutdown", close_db)

Without the need for using global... You can access the application state from the request given to any route.无需使用全局... 您可以从给任何路由的请求中访问应用程序 state。

#main.py
async def open_db() -> AsyncIOMotorClient:
    app.state.mongodb = AsyncIOMotorClient(DB_URL)

async def close_db():
    app.state.mongodb.close()

app.add_event_handler('startup', open_db)
app.add_event_handler('shutdown', close_db)

Within each request to a given route you will have access to the app state.在对给定路线的每个请求中,您将可以访问应用程序 state。 For example,例如,

@app.route('/{username}')
async def index(request: Request, username: str):
    user = await request.app.state.mongodb['auth']['users'].find_one({"username" : username})

You can even make it easier by doing something like this in your open_db function.您甚至可以通过在您的 open_db function 中执行类似的操作来使其更容易。 Specify a state value like 'users' to be a specific Collections instance.将 state 值(如“用户”)指定为特定的 Collections 实例。

async def open_db() -> AsyncIOMotorClient:
    app.state.mongodb = AsyncIOMotorClient(DB_URL)
    app.state.users = app.state.mongodb['auth']['users']

Now you can just do this,现在你可以这样做,

@app.route('/{username}')
async def index(request: Request, username: str):
    user = await request.app.state.users.find_one({"username" : username})
client = AsyncIOMotorClient()
client.get_io_loop = asyncio.get_event_loop

works for me.为我工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 RuntimeError:任务获得未来 <Future pending> 附加到另一个循环 - RuntimeError: Task got Future <Future pending> attached to a different loop asyncio.Semaphore RuntimeError:任务将 Future 附加到不同的循环 - asyncio.Semaphore RuntimeError: Task got Future attached to a different loop RuntimeError:任务 ___ 在 ___ 处运行,获得未来<future pending cb="[Protocol._on_waiter_completed()]">连接到不同的循环</future> - RuntimeError: Task ___ running at ___ at got Future <Future pending cb=[Protocol._on_waiter_completed()]> attached to a different loop Discord.py bot + Quart:尝试连接到语音通道总是会给出“任务将未来附加到不同的循环” - Discord.py bot + Quart: Trying to connect to a voice channel always gives a "task got future attached to a different loop" 使用队列导致异步异常“得到未来<future pending>附加到不同的循环”</future> - Using queues results in asyncio exception "got Future <Future pending> attached to a different loop" “有未来<Future pending>暂时使用 websocket.send(msg) 时附加到不同的循环”错误 - "got Future <Future pending> attached to a different loop" error while using websocket.send(msg) in a while 尝试使用带有 azure python SDK 的异步启动多个 ADf 触发器,我得到 RuntimeError: got Future<future pending> 附加到不同的循环</future> - Trying to start several ADf triggers using asyncio with azure python SDK, I get RuntimeError: got Future <Future pending> attached to a different loop 异步 pymongo 错误“附加到不同的循环” - Async pymongo error "attached to a different loop" asyncio '未来属于与指定为循环参数的循环不同的循环' - asyncio 'The future belongs to a different loop than the one specified as the loop argument' loop.create_task、asyncio.async/ensure_future 和 Task 有什么区别? - What's the difference between loop.create_task, asyncio.async/ensure_future and Task?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM