Closed mr-blue-sky closed 1 year ago
Hi, I would love to know if the method I presented is correct, because if so, I think it can be used by a lot of people. Thank you very much :)
Hey, Sorry. I missed your issue.
Thank you, @roman-right! I implemented a context manager like this:
class MongoClient:
_client: AsyncIOMotorClient
_database: str
def __init__(self, connection_string: str, database: str) -> None:
self._client = AsyncIOMotorClient(connection_string)
self._database = database
async def initialize(self) -> None:
await init_beanie(database=self._client[self._database], document_models=[PostDocument, CategoryDocument])
@asynccontextmanager
async def start_transaction(self) -> AsyncIterator[MongoRepository]:
async with await self._client.start_session() as session:
async with session.start_transaction():
yield MongoRepository(session)
where MongoRepository
is just a class that uses beanie
:
class MongoRepository(Repository):
_session: ClientSession
def __init__(self, session: ClientSession):
self._session = session
async def create_post(self, details: PostDetails) -> Post:
doc = PostDocument(
slug=details.slug,
title=details.title,
description=details.description,
body=details.body,
tags=details.tags,
categories=[],
)
await doc.insert(session=self._session)
return doc.to_post_model()
async def get_all_posts(self) -> AsyncIterable[Post]:
async for doc in PostDocument.find_all(session=self._session):
yield doc.to_post_model()
# more methods...
and usage via
client = MongoClient("...", "...")
await client.initialize()
async with client.start_transaction() as repo:
print(await repo.get_all_posts())
# more operations...
what do you say?
It looks neat. Do you control somehow when you stop the transaction? When endpoint returns the result or it works during another object lifetime?
@mr-blue-sky Your solution looks very neat. I am looking for ways to 'dynamically' append operations to a session/transaction in MongoDB.
Wonder how do you close the transaction when all operations are complete?
This issue is stale because it has been open 30 days with no activity.
This issue was closed because it has been stalled for 14 days with no activity.
I'd like to ping this back up - @mr-blue-sky I really dig this approach - any downsides you've encountered?
Hey, First of all, I wanted to say thank you very much for all of your hard work on this library! It's great! :blush:
Problem
I want to implement a system like this:
Domain Models
Beanie Implementation
Naive Usage
Questions
Question 1
: mymypy
is not satisfied with this statement. do you know what should I do in order to solve this?Question 2
: is it going to query all of the posts containingcategory.id
in theircategories
field correctly?await category.delete_recursively()
is atomic, in order to ensure data consistency. I thought about transactions. What should I do?Possible Solution
will it work for me?
And another question, is it necessary to pass the session to all of these methods?
Thank you very very much! :smile: