Python django.test.utils.CaptureQueriesContext() Examples

The following are 30 code examples of django.test.utils.CaptureQueriesContext(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module django.test.utils , or try the search function .
Example #1
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_for_update_sql_generated_of(self):
        """
        The backend's FOR UPDATE OF variant appears in the generated SQL when
        select_for_update() is invoked.
        """
        with transaction.atomic(), CaptureQueriesContext(connection) as ctx:
            list(Person.objects.select_related(
                'born__country',
            ).select_for_update(
                of=('born__country',),
            ).select_for_update(
                of=('self', 'born__country')
            ))
        features = connections['default'].features
        if features.select_for_update_of_column:
            expected = ['select_for_update_person"."id', 'select_for_update_country"."id']
        else:
            expected = ['select_for_update_person', 'select_for_update_country']
        expected = [connection.ops.quote_name(value) for value in expected]
        self.assertTrue(self.has_for_update_sql(ctx.captured_queries, of=expected)) 
Example #2
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_for_update_sql_generated_of(self):
        """
        The backend's FOR UPDATE OF variant appears in the generated SQL when
        select_for_update() is invoked.
        """
        with transaction.atomic(), CaptureQueriesContext(connection) as ctx:
            list(Person.objects.select_related(
                'born__country',
            ).select_for_update(
                of=('born__country',),
            ).select_for_update(
                of=('self', 'born__country')
            ))
        features = connections['default'].features
        if features.select_for_update_of_column:
            expected = ['"select_for_update_person"."id"', '"select_for_update_country"."id"']
        else:
            expected = ['"select_for_update_person"', '"select_for_update_country"']
        if features.uppercases_column_names:
            expected = [value.upper() for value in expected]
        self.assertTrue(self.has_for_update_sql(ctx.captured_queries, of=expected)) 
Example #3
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_update_parent_filtering(self):
        """
        Updating a field of a model subclass doesn't issue an UPDATE
        query constrained by an inner query (#10399).
        """
        supplier = Supplier.objects.create(
            name='Central market',
            address='610 some street',
        )
        # Capture the expected query in a database agnostic way
        with CaptureQueriesContext(connection) as captured_queries:
            Place.objects.filter(pk=supplier.pk).update(name=supplier.name)
        expected_sql = captured_queries[0]['sql']
        # Capture the queries executed when a subclassed model instance is saved.
        with CaptureQueriesContext(connection) as captured_queries:
            supplier.save(update_fields=('name',))
        for query in captured_queries:
            sql = query['sql']
            if 'UPDATE' in sql:
                self.assertEqual(expected_sql, sql) 
Example #4
Source File: test_explain.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_postgres_options(self):
        qs = Tag.objects.filter(name='test')
        test_options = [
            {'COSTS': False, 'BUFFERS': True, 'ANALYZE': True},
            {'costs': False, 'buffers': True, 'analyze': True},
            {'verbose': True, 'timing': True, 'analyze': True},
            {'verbose': False, 'timing': False, 'analyze': True},
        ]
        if connection.pg_version >= 100000:
            test_options.append({'summary': True})
        for options in test_options:
            with self.subTest(**options), transaction.atomic():
                with CaptureQueriesContext(connection) as captured_queries:
                    qs.explain(format='text', **options)
                self.assertEqual(len(captured_queries), 1)
                for name, value in options.items():
                    option = '{} {}'.format(name.upper(), 'true' if value else 'false')
                    self.assertIn(option, captured_queries[0]['sql']) 
Example #5
Source File: test_explain.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_basic(self):
        querysets = [
            Tag.objects.filter(name='test'),
            Tag.objects.filter(name='test').select_related('parent'),
            Tag.objects.filter(name='test').prefetch_related('children'),
            Tag.objects.filter(name='test').annotate(Count('children')),
            Tag.objects.filter(name='test').values_list('name'),
            Tag.objects.order_by().union(Tag.objects.order_by().filter(name='test')),
            Tag.objects.all().select_for_update().filter(name='test'),
        ]
        supported_formats = connection.features.supported_explain_formats
        all_formats = (None,) + tuple(supported_formats) + tuple(f.lower() for f in supported_formats)
        for idx, queryset in enumerate(querysets):
            for format in all_formats:
                with self.subTest(format=format, queryset=idx):
                    if connection.vendor == 'mysql':
                        # This does a query and caches the result.
                        connection.features.needs_explain_extended
                    with self.assertNumQueries(1), CaptureQueriesContext(connection) as captured_queries:
                        result = queryset.explain(format=format)
                        self.assertTrue(captured_queries[0]['sql'].startswith(connection.ops.explain_prefix))
                        self.assertIsInstance(result, str)
                        self.assertTrue(result) 
Example #6
Source File: test_explain.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_postgres_options(self):
        qs = Tag.objects.filter(name='test')
        test_options = [
            {'COSTS': False, 'BUFFERS': True, 'ANALYZE': True},
            {'costs': False, 'buffers': True, 'analyze': True},
            {'verbose': True, 'timing': True, 'analyze': True},
            {'verbose': False, 'timing': False, 'analyze': True},
        ]
        if connection.pg_version >= 100000:
            test_options.append({'summary': True})
        for options in test_options:
            with self.subTest(**options), transaction.atomic():
                with CaptureQueriesContext(connection) as captured_queries:
                    qs.explain(format='text', **options)
                self.assertEqual(len(captured_queries), 1)
                for name, value in options.items():
                    option = '{} {}'.format(name.upper(), 'true' if value else 'false')
                    self.assertIn(option, captured_queries[0]['sql']) 
Example #7
Source File: test_explain.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_basic(self):
        querysets = [
            Tag.objects.filter(name='test'),
            Tag.objects.filter(name='test').select_related('parent'),
            Tag.objects.filter(name='test').prefetch_related('children'),
            Tag.objects.filter(name='test').annotate(Count('children')),
            Tag.objects.filter(name='test').values_list('name'),
            Tag.objects.order_by().union(Tag.objects.order_by().filter(name='test')),
            Tag.objects.all().select_for_update().filter(name='test'),
        ]
        supported_formats = connection.features.supported_explain_formats
        all_formats = (None,) + tuple(supported_formats) + tuple(f.lower() for f in supported_formats)
        for idx, queryset in enumerate(querysets):
            for format in all_formats:
                with self.subTest(format=format, queryset=idx):
                    if connection.vendor == 'mysql':
                        # This does a query and caches the result.
                        connection.features.needs_explain_extended
                    with self.assertNumQueries(1), CaptureQueriesContext(connection) as captured_queries:
                        result = queryset.explain(format=format)
                        self.assertTrue(captured_queries[0]['sql'].startswith(connection.ops.explain_prefix))
                        self.assertIsInstance(result, str)
                        self.assertTrue(result) 
Example #8
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_add_field(self):
        """
        Tests adding fields to models
        """
        # Create the table
        with connection.schema_editor() as editor:
            editor.create_model(Author)
        # Ensure there's no age field
        columns = self.column_classes(Author)
        self.assertNotIn("age", columns)
        # Add the new field
        new_field = IntegerField(null=True)
        new_field.set_attributes_from_name("age")
        with CaptureQueriesContext(connection) as ctx, connection.schema_editor() as editor:
            editor.add_field(Author, new_field)
        drop_default_sql = editor.sql_alter_column_no_default % {
            'column': editor.quote_name(new_field.name),
        }
        self.assertFalse(any(drop_default_sql in query['sql'] for query in ctx.captured_queries))
        # Ensure the field is right afterwards
        columns = self.column_classes(Author)
        self.assertEqual(columns['age'][0], "IntegerField")
        self.assertEqual(columns['age'][1][6], True) 
Example #9
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_ticket11881(self):
        """
        Subqueries do not needlessly contain ORDER BY, SELECT FOR UPDATE or
        select_related() stuff.
        """
        qs = Book.objects.all().select_for_update().order_by(
            'pk').select_related('publisher').annotate(max_pk=Max('pk'))
        with CaptureQueriesContext(connection) as captured_queries:
            qs.aggregate(avg_pk=Avg('max_pk'))
            self.assertEqual(len(captured_queries), 1)
            qstr = captured_queries[0]['sql'].lower()
            self.assertNotIn('for update', qstr)
            forced_ordering = connection.ops.force_no_ordering()
            if forced_ordering:
                # If the backend needs to force an ordering we make sure it's
                # the only "ORDER BY" clause present in the query.
                self.assertEqual(
                    re.findall(r'order by (\w+)', qstr),
                    [', '.join(f[1][0] for f in forced_ordering).lower()]
                )
            else:
                self.assertNotIn('order by', qstr)
            self.assertEqual(qstr.count(' join '), 0) 
Example #10
Source File: tests.py    From django-sqlserver with MIT License 6 votes vote down vote up
def test_add_field(self):
        """
        Tests adding fields to models
        """
        # Create the table
        with connection.schema_editor() as editor:
            editor.create_model(Author)
        # Ensure there's no age field
        columns = self.column_classes(Author)
        self.assertNotIn("age", columns)
        # Add the new field
        new_field = IntegerField(null=True)
        new_field.set_attributes_from_name("age")
        with CaptureQueriesContext(connection) as ctx, connection.schema_editor() as editor:
            editor.add_field(Author, new_field)
        drop_default_sql = editor.sql_alter_column_no_default % {
            'column': editor.quote_name(new_field.name),
        }
        self.assertFalse(any(drop_default_sql in query['sql'] for query in ctx.captured_queries))
        # Ensure the field is right afterwards
        columns = self.column_classes(Author)
        self.assertEqual(columns['age'][0], "IntegerField")
        self.assertEqual(columns['age'][1][6], True) 
Example #11
Source File: test_operations.py    From django-mysql with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def test_running_without_changes(self):
        project_state = self.set_up_test_model("test_arstd")
        operation = AlterStorageEngine("Pony", from_engine="MyISAM", to_engine="InnoDB")

        assert table_storage_engine("test_arstd_pony") == "InnoDB"

        # Forwards - shouldn't actually do an ALTER since it is already InnoDB
        new_state = project_state.clone()
        operation.state_forwards("test_arstd", new_state)
        capturer = CaptureQueriesContext(connection)
        with capturer, connection.schema_editor() as editor:
            operation.database_forwards("test_arstd", editor, project_state, new_state)
        queries = [q["sql"] for q in capturer.captured_queries]
        assert not any(q.startswith("ALTER TABLE ") for q in queries)
        assert table_storage_engine("test_arstd_pony") == "InnoDB"

        # Backwards - will actually ALTER since it is going 'back' to MyISAM
        with connection.schema_editor() as editor:
            operation.database_backwards("test_arstd", editor, new_state, project_state)
        assert table_storage_engine("test_arstd_pony") == "MyISAM"

    # Copied from django core migration tests 
Example #12
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_ticket11881(self):
        """
        Subqueries do not needlessly contain ORDER BY, SELECT FOR UPDATE or
        select_related() stuff.
        """
        qs = Book.objects.all().select_for_update().order_by(
            'pk').select_related('publisher').annotate(max_pk=Max('pk'))
        with CaptureQueriesContext(connection) as captured_queries:
            qs.aggregate(avg_pk=Avg('max_pk'))
            self.assertEqual(len(captured_queries), 1)
            qstr = captured_queries[0]['sql'].lower()
            self.assertNotIn('for update', qstr)
            forced_ordering = connection.ops.force_no_ordering()
            if forced_ordering:
                # If the backend needs to force an ordering we make sure it's
                # the only "ORDER BY" clause present in the query.
                self.assertEqual(
                    re.findall(r'order by (\w+)', qstr),
                    [', '.join(f[1][0] for f in forced_ordering).lower()]
                )
            else:
                self.assertNotIn('order by', qstr)
            self.assertEqual(qstr.count(' join '), 0) 
Example #13
Source File: tests.py    From django-sqlserver with MIT License 6 votes vote down vote up
def test_ticket11881(self):
        """
        Subqueries do not needlessly contain ORDER BY, SELECT FOR UPDATE or
        select_related() stuff.
        """
        qs = Book.objects.all().select_for_update().order_by(
            'pk').select_related('publisher').annotate(max_pk=Max('pk'))
        with CaptureQueriesContext(connection) as captured_queries:
            qs.aggregate(avg_pk=Avg('max_pk'))
            self.assertEqual(len(captured_queries), 1)
            qstr = captured_queries[0]['sql'].lower()
            self.assertNotIn('for update', qstr)
            forced_ordering = connection.ops.force_no_ordering()
            if forced_ordering:
                # If the backend needs to force an ordering we make sure it's
                # the only "ORDER BY" clause present in the query.
                self.assertEqual(
                    re.findall(r'order by (\w+)', qstr),
                    [', '.join(f[1][0] for f in forced_ordering).lower()]
                )
            else:
                self.assertNotIn('order by', qstr)
            self.assertEqual(qstr.count(' join '), 0) 
Example #14
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_m2m_then_m2m_object_ids(self):
        with CaptureQueriesContext(connection) as queries:
            list(Book.objects.prefetch_related('authors__favorite_authors'))

        sql = queries[-1]['sql']
        self.assertWhereContains(sql, self.author1.name) 
Example #15
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_for_update_sql_generated_skip_locked(self):
        """
        The backend's FOR UPDATE SKIP LOCKED variant appears in
        generated SQL when select_for_update is invoked.
        """
        with transaction.atomic(), CaptureQueriesContext(connection) as ctx:
            list(Person.objects.all().select_for_update(skip_locked=True))
        self.assertTrue(self.has_for_update_sql(ctx.captured_queries, skip_locked=True)) 
Example #16
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_m2m_then_reverse_fk_object_ids(self):
        with CaptureQueriesContext(connection) as queries:
            list(Book.objects.prefetch_related('authors__addresses'))

        sql = queries[-1]['sql']
        self.assertWhereContains(sql, self.author1.name) 
Example #17
Source File: test_rasterfield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_lhs_with_index_rhs_without_index(self):
        with CaptureQueriesContext(connection) as queries:
            RasterModel.objects.filter(rast__0__contains=json.loads(JSON_RASTER)).exists()
        # It's easier to check the indexes in the generated SQL than to write
        # tests that cover all index combinations.
        self.assertRegex(queries[-1]['sql'], r'WHERE ST_Contains\([^)]*, 1, [^)]*, 1\)') 
Example #18
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_m2m_then_reverse_one_to_one_object_ids(self):
        with CaptureQueriesContext(connection) as queries:
            list(Book.objects.prefetch_related('authors__authorwithage'))

        sql = queries[-1]['sql']
        self.assertWhereContains(sql, self.author1.id) 
Example #19
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_count_join_optimization(self):
        with CaptureQueriesContext(connection) as query:
            self.article.publications.count()
        self.assertNotIn('JOIN', query[0]['sql'])
        self.assertEqual(self.nullable_target_article.publications.count(), 0) 
Example #20
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_count_join_optimization_disabled(self):
        with mock.patch.object(connection.features, 'supports_foreign_keys', False), \
                CaptureQueriesContext(connection) as query:
            self.article.publications.count()
        self.assertIn('JOIN', query[0]['sql']) 
Example #21
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_exists_join_optimization(self):
        with CaptureQueriesContext(connection) as query:
            self.article.publications.exists()
        self.assertNotIn('JOIN', query[0]['sql'])
        self.assertIs(self.nullable_target_article.publications.exists(), False) 
Example #22
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_exists_join_optimization_disabled(self):
        with mock.patch.object(connection.features, 'supports_foreign_keys', False), \
                CaptureQueriesContext(connection) as query:
            self.article.publications.exists()
        self.assertIn('JOIN', query[0]['sql']) 
Example #23
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_exists(self):
        with CaptureQueriesContext(connection) as captured_queries:
            self.assertFalse(Tag.objects.exists())
        # Ok - so the exist query worked - but did it include too many columns?
        self.assertEqual(len(captured_queries), 1)
        qstr = captured_queries[0]['sql']
        id, name = connection.ops.quote_name('id'), connection.ops.quote_name('name')
        self.assertNotIn(id, qstr)
        self.assertNotIn(name, qstr) 
Example #24
Source File: test_explain.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_mysql_text_to_traditional(self):
        # Initialize the cached property, if needed, to prevent a query for
        # the MySQL version during the QuerySet evaluation.
        connection.features.needs_explain_extended
        with CaptureQueriesContext(connection) as captured_queries:
            Tag.objects.filter(name='test').explain(format='text')
        self.assertEqual(len(captured_queries), 1)
        self.assertIn('FORMAT=TRADITIONAL', captured_queries[0]['sql']) 
Example #25
Source File: test_explain.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_mysql_extended(self):
        # Inner skip to avoid module level query for MySQL version.
        if not connection.features.needs_explain_extended:
            raise unittest.SkipTest('MySQL < 5.7 specific')
        qs = Tag.objects.filter(name='test')
        with CaptureQueriesContext(connection) as captured_queries:
            qs.explain(format='json')
        self.assertEqual(len(captured_queries), 1)
        self.assertNotIn('EXTENDED', captured_queries[0]['sql'])
        with CaptureQueriesContext(connection) as captured_queries:
            qs.explain(format='text')
        self.assertEqual(len(captured_queries), 1)
        self.assertNotIn('EXTENDED', captured_queries[0]['sql']) 
Example #26
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_for_update_sql_generated_nowait(self):
        """
        The backend's FOR UPDATE NOWAIT variant appears in
        generated SQL when select_for_update is invoked.
        """
        with transaction.atomic(), CaptureQueriesContext(connection) as ctx:
            list(Person.objects.all().select_for_update(nowait=True))
        self.assertTrue(self.has_for_update_sql(ctx.captured_queries, nowait=True)) 
Example #27
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_for_update_sql_generated_skip_locked(self):
        """
        The backend's FOR UPDATE SKIP LOCKED variant appears in
        generated SQL when select_for_update is invoked.
        """
        with transaction.atomic(), CaptureQueriesContext(connection) as ctx:
            list(Person.objects.all().select_for_update(skip_locked=True))
        self.assertTrue(self.has_for_update_sql(ctx.captured_queries, skip_locked=True)) 
Example #28
Source File: test_api.py    From normandy with Mozilla Public License 2.0 5 votes vote down vote up
def test_makes_no_db_queries(self, client):
        queries = CaptureQueriesContext(connection)
        with queries:
            res = client.get("/api/v1/classify_client/")
            assert res.status_code == 200
        assert len(queries) == 0 
Example #29
Source File: utils.py    From django-mysql with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def __enter__(self):
        self.capturer = CaptureQueriesContext(self.conn)
        self.capturer.__enter__()
        return self 
Example #30
Source File: test_api.py    From normandy with Mozilla Public License 2.0 5 votes vote down vote up
def test_apis_make_a_reasonable_number_of_db_queries(client, endpoint, Factory):
    """
    Naive versions of these views could easily make several queries
    per item, which is very slow. Make sure that isn't the case.
    """
    Factory.create_batch(100)
    queries = CaptureQueriesContext(connection)
    with queries:
        res = client.get(endpoint)
        assert res.status_code == 200
    # Anything under 100 isn't doing one query per recipe.
    assert len(queries) < 100