-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SCAL-104: Implement db transactions in mongoengine #4
Conversation
3495ef6
to
b90455e
Compare
@@ -11,17 +11,12 @@ on: | |||
tags: | |||
- 'v[0-9]+\.[0-9]+\.[0-9]+*' | |||
env: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed as we do not need to support old version of pymongo nor mongoDB and it would get more complicated to do so. We can do that later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems likely that upstream would want these cases handled before merging back in, but if this PR is just for our use then I don't see a problem with it for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I do not think we will be able to just take this PR and merge it in mongoengine, there are a lot of small details in the support for transactions in the different versions of the DBs.
Of course, they could also decide to increase the major version and say, it works only in MongoDB 4.4+ but I do not think that will be the case
@@ -506,7 +506,7 @@ def to_mongo(self, value): | |||
def prepare_query_value(self, op, value): | |||
return self.to_mongo(value) | |||
|
|||
def validate(self, value): | |||
def validate(self, value, clean=True): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warnings of my IDE, using the same function signature as in super
@@ -18,6 +21,49 @@ | |||
) | |||
|
|||
|
|||
class run_in_transaction(contextlib.ContextDecorator, contextlib.ExitStack): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The context manager and decorator
""" | ||
super().__enter__() | ||
self.conn = get_connection(self.db_alias) | ||
self.session = self.enter_context(self.conn.start_session()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now I am not testing or worrying about nested transactions or reuse of the session
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I am using the pymongo context manager for start_session I believe every session is closed
mongoengine/sessions.py
Outdated
|
||
from mongoengine.connection import DEFAULT_CONNECTION_NAME, get_connection | ||
|
||
sessions = local() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code to handle the sessions, I might clean it up and I accept suggestions about alternatives to this global
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is a poor idea to create this globally. Modules shouldnt really have side-effects on import and globals are discouraged.
I would prefer a thread_local_session
class which creates a local()
and binds a new session to it when asked, then has the free functions below as methods.
I am unsure quite how we'd pass existing sessions down to nested transactions, but there is probably a way to do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is the thing I was not able to do, I want to have something that I can access with an import, if not I need to store an instance somewhere :)
A singleton would also be nice, but I quite do not know how to do it.
I will investigate more about it
…threading local to store the sessions
b90455e
to
25d8d29
Compare
…threading local to store the sessions
Reset fork to v.23 and fix validation of inc and dec for an IntField with min_value
@@ -1173,6 +1186,9 @@ def allow_disk_use(self, enabled): | |||
|
|||
:param enabled: whether or not temporary files on disk are used | |||
""" | |||
if not IS_PYMONGO_GTE_311: | |||
return self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain this change please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The property allow_disk is not accepted in pymongo 3.11 and it was making a test fail, so I return the existing qs to avoid a failure.
Not sure if it is the right solution, but I wanted my tests green :)
|
||
with run_in_transaction(): | ||
person.save() | ||
person.to_dbref() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing an assert?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not know, it is like the test above but running inside a transaction.
I added it to be sure it was working properly even in a transaction, but I do not know how it should work :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I had a look at the to_dbref
function and I don't know what could be added to the test either :/
tests/document/test_instance.py
Outdated
|
||
person.reload() | ||
assert person.name == "Mr Test User" | ||
assert person.age == 21 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be done twice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not know, I copied the test above, maybe there is a reason, I have no clue 😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd remove it and see if the test still passes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
surely it will pass, removing assertions would not make it fail, if you want me to remove it I do not have a problem
I simply do not know why it was duplicated in the test above.
I will remove it :)
Thanks for reviewing @clembrival any questions or suggestions on the main logic and their tests, am I missing something? |
mongoengine/sessions.py
Outdated
|
||
from mongoengine.connection import DEFAULT_CONNECTION_NAME, get_connection | ||
|
||
sessions = local() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is a poor idea to create this globally. Modules shouldnt really have side-effects on import and globals are discouraged.
I would prefer a thread_local_session
class which creates a local()
and binds a new session to it when asked, then has the free functions below as methods.
I am unsure quite how we'd pass existing sessions down to nested transactions, but there is probably a way to do that.
tests/document/test_instance.py
Outdated
|
||
person.reload() | ||
assert person.name == "Mr Test User" | ||
assert person.age == 21 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd remove it and see if the test still passes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Theres more than one test with a lot going on in the transaction contexts, I think the code in transaction contexts should be limited to just the code performing database queries that need a transaction, and not include print
s, asserts
or other stuff.
No description provided.