def test_batch_select_after_new_query(self): entry1, entry2, entry3, entry4 = _create_entries(4) tag1, tag2, tag3 = _create_tags('tag1', 'tag2', 'tag3') entry1.tags.add(tag1, tag2, tag3) entry2.tags.add(tag2) entry3.tags.add(tag2, tag3) qs = Entry.objects.batch_select(Batch('tags')).order_by('id') self.failUnlessEqual([entry1, entry2, entry3, entry4], list(qs)) entry1, entry2, entry3, entry4 = list(qs) self.failUnlessEqual(set([tag1, tag2, tag3]), set(entry1.tags_all)) self.failUnlessEqual(set([tag2]), set(entry2.tags_all)) self.failUnlessEqual(set([tag2, tag3]), set(entry3.tags_all)) self.failUnlessEqual(set([]), set(entry4.tags_all)) new_qs = qs.filter(id=entry1.id) self.failUnlessEqual([entry1], list(new_qs)) entry1 = list(new_qs)[0] self.failUnlessEqual(set([tag1, tag2, tag3]), set(entry1.tags_all))
def test_batch_annotate(self): section1 = Section.objects.create(name='s1') section2 = Section.objects.create(name='s2') section3 = Section.objects.create(name='s3') entry1 = Entry.objects.create(section=section1) entry2 = Entry.objects.create(section=section1) entry3 = Entry.objects.create(section=section3) entry1.tags.add(self.tag2, self.tag3, self.tag1) entry3.tags.add(self.tag2, self.tag3) batch = Batch('entry').order_by('id').annotate(Count('tags')) sections = Section.objects.batch_select(batch).order_by('id') sections = list(sections) self.failUnlessEqual([section1, section2, section3], sections) section1, section2, section3 = sections self.failUnlessEqual([entry1, entry2], section1.entry_all) self.failUnlessEqual([], section2.entry_all) self.failUnlessEqual([entry3], section3.entry_all) self.failUnlessEqual(3, section1.entry_all[0].tags__count) self.failUnlessEqual(0, section1.entry_all[1].tags__count) self.failUnlessEqual(2, section3.entry_all[0].tags__count)
def _create_batch(self, batch_or_str, target_field_name=None): batch = batch_or_str if isinstance(batch_or_str, basestring): batch = Batch(batch_or_str) if target_field_name: batch.target_field_name = target_field_name _check_field_exists(self.model, batch.m2m_fieldname) return batch
def test_batch_select_filter(self): entries = Entry.objects.batch_select( Batch('tags').filter(name='tag2')).order_by('id') entries = list(entries) self.failUnlessEqual( [self.entry1, self.entry2, self.entry3, self.entry4], entries) entry1, entry2, entry3, entry4 = entries self.failUnlessEqual(set([self.tag2]), set(entry1.tags_all)) self.failUnlessEqual(set([self.tag2]), set(entry2.tags_all)) self.failUnlessEqual(set([self.tag2]), set(entry3.tags_all)) self.failUnlessEqual(set([]), set(entry4.tags_all))
def test_batch_reverse(self): entries = Entry.objects.batch_select( Batch('tags').order_by('name').reverse()).order_by('id') entries = list(entries) self.failUnlessEqual( [self.entry1, self.entry2, self.entry3, self.entry4], entries) entry1, entry2, entry3, entry4 = entries self.failUnlessEqual([self.tag3, self.tag2, self.tag1], entry1.tags_all) self.failUnlessEqual([self.tag2], entry2.tags_all) self.failUnlessEqual([self.tag3, self.tag2], entry3.tags_all) self.failUnlessEqual([], entry4.tags_all)
def test_batch_select_minimal_queries(self): # make sure we are only doing the number of sql queries we intend to entry1, entry2, entry3, entry4 = _create_entries(4) tag1, tag2, tag3 = _create_tags('tag1', 'tag2', 'tag3') entry1.tags.add(tag1, tag2, tag3) entry2.tags.add(tag2) entry3.tags.add(tag2, tag3) db.reset_queries() qs = Entry.objects.batch_select(Batch('tags')).order_by('id') self.failUnlessEqual([entry1, entry2, entry3, entry4], list(qs)) # this should have resulted in only two queries self.failUnlessEqual(2, len(db.connection.queries)) # double-check result is cached, and doesn't trigger more queries self.failUnlessEqual([entry1, entry2, entry3, entry4], list(qs)) self.failUnlessEqual(2, len(db.connection.queries))
def test_batch_select_caching_works(self): # make sure that query set caching still # works and doesn't alter the added fields entry1, entry2, entry3, entry4 = _create_entries(4) tag1, tag2, tag3 = _create_tags('tag1', 'tag2', 'tag3') entry1.tags.add(tag1, tag2, tag3) entry2.tags.add(tag2) entry3.tags.add(tag2, tag3) qs = Entry.objects.batch_select(Batch('tags')).order_by('id') self.failUnlessEqual([entry1, entry2, entry3, entry4], list(qs)) entry1, entry2, entry3, entry4 = list(qs) self.failUnlessEqual(set([tag1, tag2, tag3]), set(entry1.tags_all)) self.failUnlessEqual(set([tag2]), set(entry2.tags_all)) self.failUnlessEqual(set([tag2, tag3]), set(entry3.tags_all)) self.failUnlessEqual(set([]), set(entry4.tags_all))
def test_batch_select_related(self): # verify using select related doesn't tigger more queries section1 = Section.objects.create(name='s1') section2 = Section.objects.create(name='s2') section3 = Section.objects.create(name='s3') location = Location.objects.create(name='home') entry1 = Entry.objects.create(section=section1, location=location) entry2 = Entry.objects.create(section=section1) entry3 = Entry.objects.create(section=section3) entry1.tags.add(self.tag2, self.tag3, self.tag1) entry3.tags.add(self.tag2, self.tag3) db.reset_queries() batch = Batch('entry').order_by('id').select_related('location') sections = Section.objects.batch_select(batch).order_by('id') sections = list(sections) self.failUnlessEqual([section1, section2, section3], sections) section1, section2, section3 = sections self.failUnlessEqual([entry1, entry2], section1.entry_all) self.failUnlessEqual([], section2.entry_all) self.failUnlessEqual([entry3], section3.entry_all) self.failUnlessEqual(2, len(db.connection.queries)) db.reset_queries() entry1, entry2 = section1.entry_all self.failUnlessEqual(0, len(db.connection.queries)) self.failUnlessEqual(location, entry1.location) self.failUnlessEqual(0, len(db.connection.queries)) self.failUnless(entry2.location is None) self.failUnlessEqual(0, len(db.connection.queries))
def test_batch_nested(self): section1 = Section.objects.create(name='s1') entry1 = Entry.objects.create(section=section1) entry2 = Entry.objects.create(section=section1) tag1, tag2, tag3 = _create_tags('tag1', 'tag2', 'tag3') entry1.tags.add(tag1, tag3) entry2.tags.add(tag2) db.reset_queries() entry_batch = Batch('entry_set').batch_select('tags') sections = Section.objects.batch_select(entries=entry_batch) sections = list(sections) section1 = sections[0] section1_tags = [ tag for entry in section1.entries for tag in entry.tags_all ] self.failUnlessEqual(set([tag1, tag2, tag3]), set(section1_tags)) self.failUnlessEqual(3, len(db.connection.queries))
def test_batch_only(self): batch = Batch('tags').order_by('id').only('id') self._check_name_deferred(batch)
def test_batch_select_non_m2m_field(self): try: qs = Entry.objects.batch_select(Batch('title')).order_by('id') self.fail('selected field that is not m2m field') except FieldDoesNotExist: pass
def test_batch_select_non_existant_field(self): try: qs = Entry.objects.batch_select(Batch('qwerty')).order_by('id') self.fail('selected field that does not exist') except FieldDoesNotExist: pass