-
Notifications
You must be signed in to change notification settings - Fork 32
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
MemoryStore: replace mongomock with pymongo-inmemory #846
base: main
Are you sure you want to change the base?
Conversation
+1 I’ve observed some serious differences between mongomock and pymongo that can result in some tedious debugging! I think the idea of using real Mongo is much preferred. |
@@ -538,14 +535,50 @@ | |||
assert jsonstore.last_updated > start_time | |||
|
|||
|
|||
def test_eq(mongostore, memorystore, jsonstore): | |||
def test_eq(mongostore, memorystore, jsonstore, montystore): | |||
assert montystore == montystore |
Check warning
Code scanning / CodeQL
Comparison of identical values Warning test
# def __del__(self): | ||
# """ | ||
# Ensure collection is dropped from memory on object destruction, even if .close() has not been called. | ||
# """ | ||
# if self._coll is not None: | ||
# self._collection.drop() |
Check notice
Code scanning / CodeQL
Commented-out code Note
@munrojm @gpetretto I updated the first post on this PR with a specific request for help from each of you on one of the test failures. I'd appreciate any thoughts you have (adding this comment b/c I'm not sure if editing the post would trigger an email notification). |
Just committed a fix for the patch test. Was an issue with how the body data was being passed to the |
Thanks @rkingsbury for updating the MemoryStore. The limited number of features supported by mongomock was ineed an issue. jsonstore.update({"wrong_field": SubFloat(1.1), "task_id": 3}) the dictionary stored internally still contained an instance of |
Thanks for investigating! So if I understand correctly, the original problem that prompted #791 is resolved by this PR.
But it sounds like you're saying that if I were to do this:
I would get back a |
Indeed I think that this would have avoided the need for #791. I will try to make a test with the new version and see if there is no issue with that.
Yes, you will get back a class SubFloat(float):
pass
ms = MemoryStore()
ms.connect()
d = {"test": SubFloat(1.1), "normal": 1.1, "task_id": 3}
ms.update(d)
out_d = ms.query_one()
print(out_d["test"].__class__, out_d["normal"].__class__) The output with the old version is:
While with the new version is:
In the end it is not really a problem, since this makes the |
Summary
Major changes:
mongomock
withpymongo-inmemory
MemoryStore
, which can now inherit nearly all methods fromMongoStore
.MemoryStore()
instantiated with the same collection name now point to the same instance in memory. This is in contrast to previous behavior (which was somewhat unintuitive) and leads more intuitive__eq__
behavior (see MemoryStore __eq__ does not behave as expected #788 )MemoryStore
, e.g., must callconnect()
again afterrun()
.pymongo-inmemory
creates a thin wrapper aroundMongoClient()
using a downloaded instance ofmongod
, so it guaranteed to work and perform exactly like "real"pymongo
, unlikemongomock
which has some limitations and inconstencies.Performance impact
I did a basic timing test for connecting to a
FileStore
(400 files) on a system with slow (HDD) storage. On first connection,pymongo-inmemory
was slower by about 50% (19s vs. 13s), presumably because it has to download and spin up themongod
instance. On subsecquentfs.connect
callspymongo-inmemory
was at least as fast asmongomock
(12s vs. 13s).On a system with faster storage (SSD) and 800 files,
pymongo-inmemory
andmongomock
had comparable speed (26-30s for pymongo-inmemory vs. 27s for mongomock)Todos
If this is work in progress, what else needs to be done?
pyproject.toml
- (I need to open a PR for this; not necessary to complete before merging this PR).Remaining test failures / CI problems
I need some help (please!) from @munrojm and maybe @gpetretto to resolve the remaining test failures. I'll break them down one by one
test_jsonstore_orjson_options
(@gpetretto )The changes here prevent the
JSONEncodeError
from being raised, for reasons I haven't yet identified.By updating
MemoryStore
to use "real" Mongo, I was able to inherit theupdate
method fromMongoStore
rather than use the customupdate
method that had previously been used. That customupdate
is now insideMontyStore
. I suspect that a subtle difference between the two is causing this test to fail, but I haven't been able to pin it down. I would appreciate a 2nd set of eyes. I suggest comparing the twoupdate
methods side by side as a starting point.test_submission_patch
(@munrojm )For some reason the API is now generating a Bad Response code instead of code 200. This must somehow be related to
owner_store
which is aMemoryStore
, but I'm not familiar enough with the API to figure out the connectionServerSelectionTimeout
ErrorsOccasionally some tests error out because the
MemoryStore
times out. I suspect this occurs becausepymongo-inmemory
is downloading and spinning up its ownmongod
before it can run the tests. It looks like this wasn't a problem after the most recent update, so perhaps it will take care of itself. If the issue persists, I will experiment with havingpymongo-inmemory
use the built in mongo instance provided on the GH runner instead of downloading its own.Checklist
ruff
. (For guidance in fixing rule violates, see rule list)mypy
.