def test_list_item_dereference(self): """Ensure that DBRef items in ListFields are dereferenced. """ class User(Document): name = StringField() class Group(Document): members = ListField(ReferenceField(User)) User.drop_collection() Group.drop_collection() for i in range(1, 51): user = User(name="user %s" % i) user.save() group = Group(members=User.objects) group.save() group = Group(members=User.objects) group.save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) len(group_obj._data["members"]) self.assertEqual(q, 1) len(group_obj.members) self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) # Document select_related with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first().select_related() self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) # Queryset select_related with query_counter() as q: self.assertEqual(q, 0) group_objs = Group.objects.select_related() self.assertEqual(q, 2) for group_obj in group_objs: [m for m in group_obj.members] self.assertEqual(q, 2) User.drop_collection() Group.drop_collection()
def test_list_item_dereference(self): """Ensure that DBRef items in ListFields are dereferenced. """ class User(Document): name = StringField() class Group(Document): members = ListField(ReferenceField(User)) User.drop_collection() Group.drop_collection() for i in xrange(1, 51): user = User(name="user %s" % i) user.save() group = Group(members=User.objects) group.save() group = Group(members=User.objects) group.save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) len(group_obj._data["members"]) self.assertEqual(q, 1) len(group_obj.members) self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) # Document select_related with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first().select_related() self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) # Queryset select_related with query_counter() as q: self.assertEqual(q, 0) group_objs = Group.objects.select_related() self.assertEqual(q, 2) for group_obj in group_objs: [m for m in group_obj.members] self.assertEqual(q, 2) User.drop_collection() Group.drop_collection()
def test_list_item_dereference_dref_false(self): """Ensure that DBRef items in ListFields are dereferenced. """ class User(Document): name = StringField() class Group(Document): members = ListField(ReferenceField(User, dbref=False)) User.drop_collection() Group.drop_collection() for i in range(1, 51): user = User(name="user %s" % i) user.save() group = Group(members=User.objects) group.save() group.reload() # Confirm reload works with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 2) self.assertTrue(group_obj._data["members"]._dereferenced) # verifies that no additional queries gets executed # if we re-iterate over the ListField once it is # dereferenced [m for m in group_obj.members] self.assertEqual(q, 2) self.assertTrue(group_obj._data["members"]._dereferenced) # Document select_related with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first().select_related() self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) # Queryset select_related with query_counter() as q: self.assertEqual(q, 0) group_objs = Group.objects.select_related() self.assertEqual(q, 2) for group_obj in group_objs: [m for m in group_obj.members] self.assertEqual(q, 2)
def test_list_item_dereference_dref_false(self): """Ensure that DBRef items in ListFields are dereferenced. """ class User(Document): name = StringField() class Group(Document): members = ListField(ReferenceField(User, dbref=False)) User.drop_collection() Group.drop_collection() for i in range(1, 51): user = User(name='user %s' % i) user.save() group = Group(members=User.objects) group.save() group.reload() # Confirm reload works with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 2) self.assertTrue(group_obj._data['members']._dereferenced) # verifies that no additional queries gets executed # if we re-iterate over the ListField once it is # dereferenced [m for m in group_obj.members] self.assertEqual(q, 2) self.assertTrue(group_obj._data['members']._dereferenced) # Document select_related with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first().select_related() self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) # Queryset select_related with query_counter() as q: self.assertEqual(q, 0) group_objs = Group.objects.select_related() self.assertEqual(q, 2) for group_obj in group_objs: [m for m in group_obj.members] self.assertEqual(q, 2)
def test_datetime(self): resp = self.app.post( "/datetime/", data=json.dumps({ "datetime": "2010-01-01T00:00:00", }), ) response_success(resp) datetime = resp_json(resp) self.assertEqual(datetime["datetime"], "2010-01-01T00:00:00") with query_counter() as c: resp = self.app.put( "/datetime/%s/" % datetime["id"], data=json.dumps({ "datetime": "2010-01-02T00:00:00", }), ) response_success(resp) datetime = resp_json(resp) self.assertEqual(datetime["datetime"], "2010-01-02T00:00:00") self.assertEqual(c, 3) # query, update, query (reload) with query_counter() as c: resp = self.app.put( "/datetime/%s/" % datetime["id"], data=json.dumps({ "datetime": "2010-01-02T00:00:00", }), ) response_success(resp) datetime = resp_json(resp) self.assertEqual(datetime["datetime"], "2010-01-02T00:00:00") # Ideally this would be one query since we're not modifying, but # in the generic case the save method may have other side effects # and we don't know if the object was modified, so we currently # always reload. self.assertEqual(c, 2) # 2x query (with reload) # Same as above, with no body with query_counter() as c: resp = self.app.put("/datetime/%s/" % datetime["id"], data=json.dumps({})) response_success(resp) datetime = resp_json(resp) self.assertEqual(datetime["datetime"], "2010-01-02T00:00:00") self.assertEqual(c, 2) # 2x query (with reload)
def test_list_item_dereference_dref_false(self): """Ensure that DBRef items in ListFields are dereferenced. """ class User(Document): name = StringField() class Group(Document): members = ListField(ReferenceField(User, dbref=False)) User.drop_collection() Group.drop_collection() for i in xrange(1, 51): user = User(name='user %s' % i) user.save() group = Group(members=User.objects) group.save() group.reload() # Confirm reload works with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 2) # Document select_related with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first().select_related() self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) # Queryset select_related with query_counter() as q: self.assertEqual(q, 0) group_objs = Group.objects.select_related() self.assertEqual(q, 2) for group_obj in group_objs: [m for m in group_obj.members] self.assertEqual(q, 2) User.drop_collection() Group.drop_collection()
def test_list_item_dereference_dref_true_save_doesnt_cause_extra_queries( self): """Ensure that DBRef items in ListFields are dereferenced. """ class User(Document): name = StringField() class Group(Document): name = StringField() members = ListField(ReferenceField(User, dbref=True)) User.drop_collection() Group.drop_collection() for i in range(1, 51): User(name='user %s' % i).save() Group(name="Test", members=User.objects).save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) group_obj.name = "new test" group_obj.save() self.assertEqual(q, 2)
def test_collision(self): """ Make sure that the right object is returned, even in case of a hash collision. """ faux_obj = self.BlogPost.objects.get(title='Second Title') with query_counter() as q: obj1 = self.mongo_cache.get(self.BlogPost, 'title', 'First Title') # manually override the data in First Post's cache_key to point to # the Second Title's object, simulating a collision cache_key, flag_key = self.mongo_cache.get_keys( self.BlogPost, 'title', 'First Title') self.mongo_cache.redis.set(cache_key, self.mongo_cache.serialize(faux_obj)) obj2 = self.mongo_cache.get( self.BlogPost, 'title', 'First Title' ) # this should return the valid obj and invalidate the cache obj3 = self.mongo_cache.get( self.BlogPost, 'title', 'First Title') # this should cache the right obj obj4 = self.mongo_cache.get( self.BlogPost, 'title', 'First Title') # this should already have the valid obj cached self.assertEqual(obj1, obj2) self.assertEqual(obj1, obj3) self.assertEqual(obj1, obj4) self.assertEqual( q, 3 ) # 1st query + query after a cache collision + query that cached the right obj
def test_select_related_follows_embedded_referencefields(self): class Song(Document): title = StringField() class PlaylistItem(EmbeddedDocument): song = ReferenceField("Song") class Playlist(Document): items = ListField(EmbeddedDocumentField("PlaylistItem")) Playlist.drop_collection() Song.drop_collection() songs = [Song.objects.create(title="song %d" % i) for i in range(3)] items = [PlaylistItem(song=song) for song in songs] playlist = Playlist.objects.create(items=items) with query_counter() as q: self.assertEqual(q, 0) playlist = Playlist.objects.first().select_related() songs = [item.song for item in playlist.items] self.assertEqual(q, 2)
def test_list_item_dereference_dref_true_save_doesnt_cause_extra_queries(self): """Ensure that DBRef items in ListFields are dereferenced. """ class User(Document): name = StringField() class Group(Document): name = StringField() members = ListField(ReferenceField(User, dbref=True)) User.drop_collection() Group.drop_collection() for i in xrange(1, 51): User(name='user %s' % i).save() Group(name="Test", members=User.objects).save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) group_obj.name = "new test" group_obj.save() self.assertEqual(q, 2)
def test_collision(self): """ Make sure that the right object is returned, even in case of a hash collision. """ faux_obj = self.BlogPost.objects.get(title='Second Title') with query_counter() as q: obj1 = self.mongo_cache.get(self.BlogPost, 'title', 'First Title') # manually override the data in First Post's cache_key to point to # the Second Title's object, simulating a collision cache_key, flag_key = self.mongo_cache.get_keys( self.BlogPost,'title', 'First Title' ) self.mongo_cache.redis.set( cache_key, self.mongo_cache.serialize(faux_obj) ) obj2 = self.mongo_cache.get(self.BlogPost, 'title', 'First Title') # this should return the valid obj and invalidate the cache obj3 = self.mongo_cache.get(self.BlogPost, 'title', 'First Title') # this should cache the right obj obj4 = self.mongo_cache.get(self.BlogPost, 'title', 'First Title') # this should already have the valid obj cached self.assertEqual(obj1, obj2) self.assertEqual(obj1, obj3) self.assertEqual(obj1, obj4) self.assertEqual(q, 3) # 1st query + query after a cache collision + query that cached the right obj
def test_query_counter(self): connect('mongoenginetest') db = get_db() collection = db.query_counter collection.drop() def issue_1_count_query(): collection.find({}).count() def issue_1_insert_query(): collection.insert_one({'test': 'garbage'}) def issue_1_find_query(): collection.find_one() counter = 0 with query_counter() as q: self.assertEqual(q, counter) self.assertEqual(q, counter) # Ensures previous count query did not get counted for _ in range(10): issue_1_insert_query() counter += 1 self.assertEqual(q, counter) for _ in range(4): issue_1_find_query() counter += 1 self.assertEqual(q, counter) for _ in range(3): issue_1_count_query() counter += 1 self.assertEqual(q, counter)
def test_datetime(self): resp = self.app.post('/datetime/', data=json.dumps({ 'datetime': '2010-01-01T00:00:00', })) response_success(resp) datetime = json.loads(resp.data) self.assertEqual(datetime['datetime'], '2010-01-01T00:00:00+00:00') with query_counter() as c: resp = self.app.put('/datetime/%s/' % datetime['id'], data=json.dumps({ 'datetime': '2010-01-02T00:00:00', })) response_success(resp) datetime = json.loads(resp.data) self.assertEqual(datetime['datetime'], '2010-01-02T00:00:00+00:00') self.assertEqual(c, 3) # query, update, query (reload) with query_counter() as c: resp = self.app.put('/datetime/%s/' % datetime['id'], data=json.dumps({ 'datetime': '2010-01-02T00:00:00', })) response_success(resp) datetime = json.loads(resp.data) self.assertEqual(datetime['datetime'], '2010-01-02T00:00:00+00:00') # Ideally this would be one query since we're not modifying, but # in the generic case the save method may have other side effects # and we don't know if the object was modified, so we currently # always reload. self.assertEqual(c, 2) # 2x query (with reload) # Same as above, with no body with query_counter() as c: resp = self.app.put('/datetime/%s/' % datetime['id'], data=json.dumps({})) response_success(resp) datetime = json.loads(resp.data) self.assertEqual(datetime['datetime'], '2010-01-02T00:00:00+00:00') self.assertEqual(c, 2) # 2x query (with reload)
def test_query_counter_alias(self): """query_counter works properly with db aliases?""" clear_document_registry() # Register a connection with db_alias testdb-1 register_connection("testdb-1", "mongoenginetest2") class A(Document): """Uses default db_alias""" name = StringField() class B(Document): """Uses testdb-1 db_alias""" name = StringField() meta = {"db_alias": "testdb-1"} A.drop_collection() B.drop_collection() with query_counter() as q: assert q == 0 A.objects.create(name="A") assert q == 1 a = A.objects.first() assert q == 2 a.name = "Test A" a.save() assert q == 3 # querying the other db should'nt alter the counter B.objects().first() assert q == 3 with query_counter(alias="testdb-1") as q: assert q == 0 B.objects.create(name="B") assert q == 1 b = B.objects.first() assert q == 2 b.name = "Test B" b.save() assert b.name == "Test B" assert q == 3 # querying the other db should'nt alter the counter A.objects().first() assert q == 3
def test_generic_reference_orphan_dbref(self): """Ensure that generic orphan DBRef items in ListFields are dereferenced. """ class UserA(Document): name = StringField() class UserB(Document): name = StringField() class UserC(Document): name = StringField() class Group(Document): members = ListField(GenericReferenceField()) UserA.drop_collection() UserB.drop_collection() UserC.drop_collection() Group.drop_collection() members = [] for i in range(1, 51): a = UserA(name='User A %s' % i) a.save() b = UserB(name='User B %s' % i) b.save() c = UserC(name='User C %s' % i) c.save() members += [a, b, c] group = Group(members=members) group.save() # Delete one UserA instance so that there is # an orphan DBRef in the GenericReference ListField UserA.objects[0].delete() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 4) self.assertTrue(group_obj._data['members']._dereferenced) [m for m in group_obj.members] self.assertEqual(q, 4) self.assertTrue(group_obj._data['members']._dereferenced) UserA.drop_collection() UserB.drop_collection() UserC.drop_collection() Group.drop_collection()
def test_generic_reference_orphan_dbref(self): """Ensure that generic orphan DBRef items in ListFields are dereferenced. """ class UserA(Document): name = StringField() class UserB(Document): name = StringField() class UserC(Document): name = StringField() class Group(Document): members = ListField(GenericReferenceField()) UserA.drop_collection() UserB.drop_collection() UserC.drop_collection() Group.drop_collection() members = [] for i in range(1, 51): a = UserA(name="User A %s" % i) a.save() b = UserB(name="User B %s" % i) b.save() c = UserC(name="User C %s" % i) c.save() members += [a, b, c] group = Group(members=members) group.save() # Delete one UserA instance so that there is # an orphan DBRef in the GenericReference ListField UserA.objects[0].delete() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 4) self.assertTrue(group_obj._data["members"]._dereferenced) [m for m in group_obj.members] self.assertEqual(q, 4) self.assertTrue(group_obj._data["members"]._dereferenced) UserA.drop_collection() UserB.drop_collection() UserC.drop_collection() Group.drop_collection()
def test_invalidate(self): """Make sure simple cache invalidation works.""" with query_counter() as q: self.mongo_cache.get(self.BlogPost, 'title', 'First Title') self.mongo_cache.invalidate(self.BlogPost, 'title', 'First Title') bp = self.mongo_cache.get(self.BlogPost, 'title', 'First Title') self.mongo_cache.invalidate(bp.__class__, 'title', bp.title) self.mongo_cache.get(self.BlogPost, 'title', 'First Title') self.assertEqual(q, 3)
def test_datetime(self): resp = self.app.post('/datetime/', data=json.dumps({ 'datetime': '2010-01-01T00:00:00', })) response_success(resp) datetime = json.loads(resp.data) self.assertEqual(datetime['datetime'], '2010-01-01T00:00:00+00:00') with query_counter() as c: resp = self.app.put('/datetime/%s/' % datetime['id'], data=json.dumps({ 'datetime': '2010-01-02T00:00:00', })) response_success(resp) datetime = json.loads(resp.data) self.assertEqual(datetime['datetime'], '2010-01-02T00:00:00+00:00') self.assertEqual(c, 3) # query, update, query (reload) with query_counter() as c: resp = self.app.put('/datetime/%s/' % datetime['id'], data=json.dumps({ 'datetime': '2010-01-02T00:00:00', })) response_success(resp) datetime = json.loads(resp.data) self.assertEqual(datetime['datetime'], '2010-01-02T00:00:00+00:00') # Ideally this would be one query since we're not modifying, but # in the generic case the save method may have other side effects # and we don't know if the object was modified, so we currently # always reload. self.assertEqual(c, 2) # 2x query (with reload) # Same as above, with no body with query_counter() as c: resp = self.app.put('/datetime/%s/' % datetime['id'], data=json.dumps({ })) response_success(resp) datetime = json.loads(resp.data) self.assertEqual(datetime['datetime'], '2010-01-02T00:00:00+00:00') self.assertEqual(c, 2) # 2x query (with reload)
def test_query_counter(self): connect('mongoenginetest') db = get_db() db.test.find({}) with query_counter() as q: self.assertEqual(0, q) for i in xrange(1, 51): db.test.find({}).count() self.assertEqual(50, q)
def test_query_counter(self): connect('mongoenginetest') db = get_db() db.test.find({}) with query_counter() as q: self.assertEqual(0, q) for i in range(1, 51): db.test.find({}).count() self.assertEqual(50, q)
def test_query_counter_counts_getmore_queries(self): connect('mongoenginetest') db = get_db() collection = db.query_counter collection.drop() many_docs = [{'test': 'garbage %s' % i} for i in range(150)] collection.insert_many(many_docs) # first batch of documents contains 101 documents with query_counter() as q: self.assertEqual(q, 0) list(collection.find()) self.assertEqual(q, 2) # 1st select + 1 getmore
def test_get_db_queries(self): """ Make sure consecutive calls to mongo_cache.get don't hit the database for the same doc. """ with query_counter() as q: for i in range(3): self.mongo_cache.get(self.BlogPost, 'title', 'First Title') self.mongo_cache.get(self.BlogPost, 'title', 'Second Title') # Only 2 queries to Mongo should be performed - one for caching # First Title and one for Second Title self.assertEqual(q, 2)
def test_query_counter_counts_getmore_queries(self): connect("mongoenginetest") db = get_db() collection = db.query_counter collection.drop() many_docs = [{"test": "garbage %s" % i} for i in range(150)] collection.insert_many( many_docs) # first batch of documents contains 101 documents with query_counter() as q: assert q == 0 list(collection.find()) assert q == 2 # 1st select + 1 getmore
def test_model_instance_dereference(self): class TestDocument(Document): user = ModelField() timestamp = DateTimeField(required=True, default=timezone.now) TestDocument.drop_collection() document = TestDocument(user=self.user) document.save() with query_counter() as count: self.assertEqual(count, 0) instance = TestDocument.objects.order_by('-timestamp').first() self.assertEqual(count, 1)
def test_query_counter_temporarily_modifies_profiling_level(self): connect('mongoenginetest') db = get_db() initial_profiling_level = db.profiling_level() try: NEW_LEVEL = 1 db.set_profiling_level(NEW_LEVEL) self.assertEqual(db.profiling_level(), NEW_LEVEL) with query_counter() as q: self.assertEqual(db.profiling_level(), 2) self.assertEqual(db.profiling_level(), NEW_LEVEL) except Exception: db.set_profiling_level(initial_profiling_level) # Ensures it gets reseted no matter the outcome of the test raise
def test_query_counter_temporarily_modifies_profiling_level(self): connect("mongoenginetest") db = get_db() initial_profiling_level = db.profiling_level() try: new_level = 1 db.set_profiling_level(new_level) assert db.profiling_level() == new_level with query_counter(): assert db.profiling_level() == 2 assert db.profiling_level() == new_level except Exception: db.set_profiling_level( initial_profiling_level ) # Ensures it gets reseted no matter the outcome of the test raise
def test_query_counter_ignores_particular_queries(self): connect('mongoenginetest') db = get_db() collection = db.query_counter collection.insert_many([{'test': 'garbage %s' % i} for i in range(10)]) with query_counter() as q: self.assertEqual(q, 0) cursor = collection.find() self.assertEqual(q, 0) # cursor wasn't opened yet _ = next(cursor) # opens the cursor and fires the find query self.assertEqual(q, 1) cursor.close() # issues a `killcursors` query that is ignored by the context self.assertEqual(q, 1) _ = db.system.indexes.find_one() # queries on db.system.indexes are ignored as well self.assertEqual(q, 1)
def test_query_counter(self): connect("mongoenginetest") db = get_db() collection = db.query_counter collection.drop() def issue_1_count_query(): count_documents(collection, {}) def issue_1_insert_query(): collection.insert_one({"test": "garbage"}) def issue_1_find_query(): collection.find_one() counter = 0 with query_counter() as q: self.assertEqual(q, counter) self.assertEqual( q, counter) # Ensures previous count query did not get counted for _ in range(10): issue_1_insert_query() counter += 1 self.assertEqual(q, counter) for _ in range(4): issue_1_find_query() counter += 1 self.assertEqual(q, counter) for _ in range(3): issue_1_count_query() counter += 1 self.assertEqual(q, counter) self.assertEqual(int(q), counter) # test __int__ self.assertEqual(repr(q), str(int(q))) # test __repr__ self.assertGreater(q, -1) # test __gt__ self.assertGreaterEqual(q, int(q)) # test __gte__ self.assertNotEqual(q, -1) self.assertLess(q, 1000) self.assertLessEqual(q, int(q))
def test_query_counter(self): connect("mongoenginetest") db = get_db() collection = db.query_counter collection.drop() def issue_1_count_query(): count_documents(collection, {}) def issue_1_insert_query(): collection.insert_one({"test": "garbage"}) def issue_1_find_query(): collection.find_one() counter = 0 with query_counter() as q: assert q == counter assert q == counter # Ensures previous count query did not get counted for _ in range(10): issue_1_insert_query() counter += 1 assert q == counter for _ in range(4): issue_1_find_query() counter += 1 assert q == counter for _ in range(3): issue_1_count_query() counter += 1 assert q == counter assert int(q) == counter # test __int__ assert repr(q) == str(int(q)) # test __repr__ assert q > -1 # test __gt__ assert q >= int(q) # test __gte__ assert q != -1 assert q < 1000 assert q <= int(q)
def test_lazy_reference_embedded_dereferencing(self): # Test case for #2375 # -- Test documents class Author(Document): name = StringField() class AuthorReference(EmbeddedDocument): author = LazyReferenceField(Author) class Book(Document): authors = EmbeddedDocumentListField(AuthorReference) # -- Cleanup Author.drop_collection() Book.drop_collection() # -- Create test data author_1 = Author(name="A1").save() author_2 = Author(name="A2").save() author_3 = Author(name="A3").save() book = Book( authors=[ AuthorReference(author=author_1), AuthorReference(author=author_2), AuthorReference(author=author_3), ] ).save() with query_counter() as qc: book = Book.objects.first() # Accessing the list must not trigger dereferencing. book.authors assert qc == 1 for ref in book.authors: with pytest.raises(AttributeError): ref["author"].name assert isinstance(ref.author, LazyReference) assert isinstance(ref.author.id, ObjectId)
def test_list_item_dereference_orphan_dbref(self): """Ensure that orphan DBRef items in ListFields are dereferenced. """ class User(Document): name = StringField() class Group(Document): members = ListField(ReferenceField(User, dbref=False)) User.drop_collection() Group.drop_collection() for i in range(1, 51): user = User(name="user %s" % i) user.save() group = Group(members=User.objects) group.save() group.reload() # Confirm reload works # Delete one User so one of the references in the # Group.members list is an orphan DBRef User.objects[0].delete() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 2) self.assertTrue(group_obj._data["members"]._dereferenced) # verifies that no additional queries gets executed # if we re-iterate over the ListField once it is # dereferenced [m for m in group_obj.members] self.assertEqual(q, 2) self.assertTrue(group_obj._data["members"]._dereferenced) User.drop_collection() Group.drop_collection()
def test_list_item_dereference_orphan_dbref(self): """Ensure that orphan DBRef items in ListFields are dereferenced. """ class User(Document): name = StringField() class Group(Document): members = ListField(ReferenceField(User, dbref=False)) User.drop_collection() Group.drop_collection() for i in range(1, 51): user = User(name='user %s' % i) user.save() group = Group(members=User.objects) group.save() group.reload() # Confirm reload works # Delete one User so one of the references in the # Group.members list is an orphan DBRef User.objects[0].delete() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 2) self.assertTrue(group_obj._data['members']._dereferenced) # verifies that no additional queries gets executed # if we re-iterate over the ListField once it is # dereferenced [m for m in group_obj.members] self.assertEqual(q, 2) self.assertTrue(group_obj._data['members']._dereferenced) User.drop_collection() Group.drop_collection()
def test_query_counter_ignores_particular_queries(self): connect("mongoenginetest") db = get_db() collection = db.query_counter collection.insert_many([{"test": "garbage %s" % i} for i in range(10)]) with query_counter() as q: assert q == 0 cursor = collection.find() assert q == 0 # cursor wasn't opened yet _ = next(cursor) # opens the cursor and fires the find query assert q == 1 cursor.close( ) # issues a `killcursors` query that is ignored by the context assert q == 1 _ = (db.system.indexes.find_one() ) # queries on db.system.indexes are ignored as well assert q == 1
def test_generic_reference_save_doesnt_cause_extra_queries(self): class UserA(Document): name = StringField() class UserB(Document): name = StringField() class UserC(Document): name = StringField() class Group(Document): name = StringField() members = ListField(GenericReferenceField()) UserA.drop_collection() UserB.drop_collection() UserC.drop_collection() Group.drop_collection() members = [] for i in xrange(1, 51): a = UserA(name='User A %s' % i).save() b = UserB(name='User B %s' % i).save() c = UserC(name='User C %s' % i).save() members += [a, b, c] Group(name="test", members=members).save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) group_obj.name = "new test" group_obj.save() self.assertEqual(q, 2)
def test_query_counter_temporarily_modifies_profiling_level(self): connect("mongoenginetest") db = get_db() def _current_profiling_level(): return db.command({"profile": -1})["was"] def _set_profiling_level(lvl): db.command({"profile": lvl}) initial_profiling_level = _current_profiling_level() try: new_level = 1 _set_profiling_level(new_level) assert _current_profiling_level() == new_level with query_counter(): assert _current_profiling_level() == 2 assert _current_profiling_level() == new_level except Exception: _set_profiling_level( initial_profiling_level ) # Ensures it gets reseted no matter the outcome of the test raise
def test_dict_field(self): class UserA(Document): name = StringField() class UserB(Document): name = StringField() class UserC(Document): name = StringField() class Group(Document): members = DictField() UserA.drop_collection() UserB.drop_collection() UserC.drop_collection() Group.drop_collection() members = [] for i in range(1, 51): a = UserA(name='User A %s' % i) a.save() b = UserB(name='User B %s' % i) b.save() c = UserC(name='User C %s' % i) c.save() members += [a, b, c] group = Group(members={str(u.id): u for u in members}) group.save() group = Group(members={str(u.id): u for u in members}) group.save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) for k, m in group_obj.members.iteritems(): self.assertIn('User', m.__class__.__name__) # Document select_related with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first().select_related() self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) for k, m in group_obj.members.iteritems(): self.assertIn('User', m.__class__.__name__) # Queryset select_related with query_counter() as q: self.assertEqual(q, 0) group_objs = Group.objects.select_related() self.assertEqual(q, 4) for group_obj in group_objs: [m for m in group_obj.members] self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) for k, m in group_obj.members.iteritems(): self.assertIn('User', m.__class__.__name__) Group.objects.delete() Group().save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 1) self.assertEqual(group_obj.members, {}) UserA.drop_collection() UserB.drop_collection() UserC.drop_collection() Group.drop_collection()
def test_generic_reference_map_field(self): class UserA(Document): name = StringField() class UserB(Document): name = StringField() class UserC(Document): name = StringField() class Group(Document): members = MapField(GenericReferenceField()) UserA.drop_collection() UserB.drop_collection() UserC.drop_collection() Group.drop_collection() members = [] for i in xrange(1, 51): a = UserA(name='User A %s' % i) a.save() b = UserB(name='User B %s' % i) b.save() c = UserC(name='User C %s' % i) c.save() members += [a, b, c] group = Group(members=dict([(str(u.id), u) for u in members])) group.save() group = Group(members=dict([(str(u.id), u) for u in members])) group.save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) for k, m in group_obj.members.iteritems(): self.assertTrue('User' in m.__class__.__name__) # Document select_related with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first().select_related() self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) for k, m in group_obj.members.iteritems(): self.assertTrue('User' in m.__class__.__name__) # Queryset select_related with query_counter() as q: self.assertEqual(q, 0) group_objs = Group.objects.select_related() self.assertEqual(q, 4) for group_obj in group_objs: [m for m in group_obj.members] self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) for k, m in group_obj.members.iteritems(): self.assertTrue('User' in m.__class__.__name__) Group.objects.delete() Group().save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 1) UserA.drop_collection() UserB.drop_collection() UserC.drop_collection() Group.drop_collection()
def test_dict_field_no_field_inheritance(self): class UserA(Document): name = StringField() meta = {'allow_inheritance': False} class Group(Document): members = DictField() UserA.drop_collection() Group.drop_collection() members = [] for i in xrange(1, 51): a = UserA(name='User A %s' % i) a.save() members += [a] group = Group(members=dict([(str(u.id), u) for u in members])) group.save() group = Group(members=dict([(str(u.id), u) for u in members])) group.save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) for k, m in group_obj.members.iteritems(): self.assertTrue(isinstance(m, UserA)) # Document select_related with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first().select_related() self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) for k, m in group_obj.members.iteritems(): self.assertTrue(isinstance(m, UserA)) # Queryset select_related with query_counter() as q: self.assertEqual(q, 0) group_objs = Group.objects.select_related() self.assertEqual(q, 2) for group_obj in group_objs: [m for m in group_obj.members] self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) for k, m in group_obj.members.iteritems(): self.assertTrue(isinstance(m, UserA)) UserA.drop_collection() Group.drop_collection()
def test_map_field_reference(self): class User(Document): name = StringField() class Group(Document): members = MapField(ReferenceField(User)) User.drop_collection() Group.drop_collection() members = [] for i in xrange(1, 51): user = User(name='user %s' % i) user.save() members.append(user) group = Group(members=dict([(str(u.id), u) for u in members])) group.save() group = Group(members=dict([(str(u.id), u) for u in members])) group.save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 2) for k, m in group_obj.members.iteritems(): self.assertTrue(isinstance(m, User)) # Document select_related with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first().select_related() self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) for k, m in group_obj.members.iteritems(): self.assertTrue(isinstance(m, User)) # Queryset select_related with query_counter() as q: self.assertEqual(q, 0) group_objs = Group.objects.select_related() self.assertEqual(q, 2) for group_obj in group_objs: [m for m in group_obj.members] self.assertEqual(q, 2) for k, m in group_obj.members.iteritems(): self.assertTrue(isinstance(m, User)) User.drop_collection() Group.drop_collection()
def test_list_field_complex(self): class UserA(Document): name = StringField() class UserB(Document): name = StringField() class UserC(Document): name = StringField() class Group(Document): members = ListField() UserA.drop_collection() UserB.drop_collection() UserC.drop_collection() Group.drop_collection() members = [] for i in xrange(1, 51): a = UserA(name='User A %s' % i) a.save() b = UserB(name='User B %s' % i) b.save() c = UserC(name='User C %s' % i) c.save() members += [a, b, c] group = Group(members=members) group.save() group = Group(members=members) group.save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) for m in group_obj.members: self.assertTrue('User' in m.__class__.__name__) # Document select_related with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first().select_related() self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) for m in group_obj.members: self.assertTrue('User' in m.__class__.__name__) # Queryset select_related with query_counter() as q: self.assertEqual(q, 0) group_objs = Group.objects.select_related() self.assertEqual(q, 4) for group_obj in group_objs: [m for m in group_obj.members] self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) for m in group_obj.members: self.assertTrue('User' in m.__class__.__name__) UserA.drop_collection() UserB.drop_collection() UserC.drop_collection() Group.drop_collection()
def test_recursive_reference(self): """Ensure that ReferenceFields can reference their own documents. """ class Employee(Document): name = StringField() boss = ReferenceField('self') friends = ListField(ReferenceField('self')) Employee.drop_collection() bill = Employee(name='Bill Lumbergh') bill.save() michael = Employee(name='Michael Bolton') michael.save() samir = Employee(name='Samir Nagheenanajar') samir.save() friends = [michael, samir] peter = Employee(name='Peter Gibbons', boss=bill, friends=friends) peter.save() Employee(name='Funky Gibbon', boss=bill, friends=friends).save() Employee(name='Funky Gibbon', boss=bill, friends=friends).save() Employee(name='Funky Gibbon', boss=bill, friends=friends).save() with query_counter() as q: self.assertEqual(q, 0) peter = Employee.objects.with_id(peter.id) self.assertEqual(q, 1) peter.boss self.assertEqual(q, 2) peter.friends self.assertEqual(q, 3) # Document select_related with query_counter() as q: self.assertEqual(q, 0) peter = Employee.objects.with_id(peter.id).select_related() self.assertEqual(q, 2) self.assertEqual(peter.boss, bill) self.assertEqual(q, 2) self.assertEqual(peter.friends, friends) self.assertEqual(q, 2) # Queryset select_related with query_counter() as q: self.assertEqual(q, 0) employees = Employee.objects(boss=bill).select_related() self.assertEqual(q, 2) for employee in employees: self.assertEqual(employee.boss, bill) self.assertEqual(q, 2) self.assertEqual(employee.friends, friends) self.assertEqual(q, 2)
def test_generic_reference_map_field(self): class UserA(Document): name = StringField() class UserB(Document): name = StringField() class UserC(Document): name = StringField() class Group(Document): members = MapField(GenericReferenceField()) UserA.drop_collection() UserB.drop_collection() UserC.drop_collection() Group.drop_collection() members = [] for i in range(1, 51): a = UserA(name='User A %s' % i) a.save() b = UserB(name='User B %s' % i) b.save() c = UserC(name='User C %s' % i) c.save() members += [a, b, c] group = Group(members={str(u.id): u for u in members}) group.save() group = Group(members={str(u.id): u for u in members}) group.save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) for k, m in iteritems(group_obj.members): self.assertIn('User', m.__class__.__name__) # Document select_related with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first().select_related() self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) for k, m in iteritems(group_obj.members): self.assertIn('User', m.__class__.__name__) # Queryset select_related with query_counter() as q: self.assertEqual(q, 0) group_objs = Group.objects.select_related() self.assertEqual(q, 4) for group_obj in group_objs: [m for m in group_obj.members] self.assertEqual(q, 4) [m for m in group_obj.members] self.assertEqual(q, 4) for k, m in iteritems(group_obj.members): self.assertIn('User', m.__class__.__name__) Group.objects.delete() Group().save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 1) UserA.drop_collection() UserB.drop_collection() UserC.drop_collection() Group.drop_collection()
def test_dict_field_no_field_inheritance(self): class UserA(Document): name = StringField() meta = {'allow_inheritance': False} class Group(Document): members = DictField() UserA.drop_collection() Group.drop_collection() members = [] for i in range(1, 51): a = UserA(name='User A %s' % i) a.save() members += [a] group = Group(members={str(u.id): u for u in members}) group.save() group = Group(members={str(u.id): u for u in members}) group.save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) for k, m in iteritems(group_obj.members): self.assertIsInstance(m, UserA) # Document select_related with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first().select_related() self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) for k, m in iteritems(group_obj.members): self.assertIsInstance(m, UserA) # Queryset select_related with query_counter() as q: self.assertEqual(q, 0) group_objs = Group.objects.select_related() self.assertEqual(q, 2) for group_obj in group_objs: [m for m in group_obj.members] self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) for k, m in iteritems(group_obj.members): self.assertIsInstance(m, UserA) UserA.drop_collection() Group.drop_collection()
def test_map_field_reference(self): class User(Document): name = StringField() class Group(Document): members = MapField(ReferenceField(User)) User.drop_collection() Group.drop_collection() members = [] for i in range(1, 51): user = User(name='user %s' % i) user.save() members.append(user) group = Group(members={str(u.id): u for u in members}) group.save() group = Group(members={str(u.id): u for u in members}) group.save() with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first() self.assertEqual(q, 1) [m for m in group_obj.members] self.assertEqual(q, 2) for k, m in iteritems(group_obj.members): self.assertIsInstance(m, User) # Document select_related with query_counter() as q: self.assertEqual(q, 0) group_obj = Group.objects.first().select_related() self.assertEqual(q, 2) [m for m in group_obj.members] self.assertEqual(q, 2) for k, m in iteritems(group_obj.members): self.assertIsInstance(m, User) # Queryset select_related with query_counter() as q: self.assertEqual(q, 0) group_objs = Group.objects.select_related() self.assertEqual(q, 2) for group_obj in group_objs: [m for m in group_obj.members] self.assertEqual(q, 2) for k, m in iteritems(group_obj.members): self.assertIsInstance(m, User) User.drop_collection() Group.drop_collection()
def test_query_counter_does_not_swallow_exception(self): with self.assertRaises(TypeError): with query_counter() as q: raise TypeError()