Ejemplo n.º 1
0
def pt_visual_explain(queryset, display=True):
    if not have_program("pt-visual-explain"):  # pragma: no cover
        raise OSError("pt-visual-explain doesn't appear to be installed")

    connection = connections[queryset.db]
    capturer = CaptureQueriesContext(connection)
    with capturer, connection.cursor() as cursor:
        sql, params = queryset.query.sql_with_params()
        cursor.execute("EXPLAIN " + sql, params)

    queries = [q["sql"] for q in capturer.captured_queries]
    # Take the last - django may have just opened up a connection in which
    # case it would have run initialization command[s]
    explain_query = queries[-1]

    # Now do the explain and pass through pt-visual-explain
    mysql_command = settings_to_cmd_args(connection.settings_dict) + [
        "-e",
        explain_query,
    ]
    mysql = subprocess.Popen(mysql_command, stdout=subprocess.PIPE)
    visual_explain = subprocess.Popen(["pt-visual-explain", "-"],
                                      stdin=mysql.stdout,
                                      stdout=subprocess.PIPE)
    mysql.stdout.close()
    explanation = visual_explain.communicate()[0].decode(encoding="utf-8")
    if display:
        print(explanation)
    else:
        return explanation
Ejemplo n.º 2
0
def pt_visual_explain(queryset, display=True):
    if not have_program('pt-visual-explain'):  # pragma: no cover
        raise OSError("pt-visual-explain doesn't appear to be installed")

    connection = connections[queryset.db]
    capturer = CaptureQueriesContext(connection)
    with capturer, connection.cursor() as cursor:
        sql, params = queryset.query.sql_with_params()
        cursor.execute('EXPLAIN ' + sql, params)

    queries = [q['sql'] for q in capturer.captured_queries]
    # Take the last - django may have just opened up a connection in which
    # case it would have run initialization command[s]
    explain_query = queries[-1]

    # Now do the explain and pass through pt-visual-explain
    mysql_command = (
        settings_to_cmd_args(connection.settings_dict) +
        ['-e', explain_query]
    )
    mysql = Popen(mysql_command, stdout=PIPE)
    visual_explain = Popen(
        ['pt-visual-explain', '-'],
        stdin=mysql.stdout,
        stdout=PIPE
    )
    mysql.stdout.close()
    explanation = visual_explain.communicate()[0].decode(encoding="utf-8")
    if display:
        print(explanation)
    else:
        return explanation
Ejemplo n.º 3
0
        VanillaAuthor.objects.create(name="pants")
        VanillaAuthor.objects.create(name="Beta")
        VanillaAuthor.objects.create(name="pants")

        bad_authors = VanillaAuthor.objects.filter(name="pants")

        assert bad_authors.count() == 2

        with captured_stdout():
            for author in SmartIterator(bad_authors, report_progress=True):
                author.delete()

        assert bad_authors.count() == 0


@skipUnless(have_program('pt-visual-explain'),
            "pt-visual-explain must be installed")
class VisualExplainTests(TestCase):
    def test_basic(self):
        with captured_stdout() as capture:
            Author.objects.all().pt_visual_explain()
        output = capture.getvalue()
        # Can't be too strict about the output since different database and pt-
        # visual-explain versions give different output
        assert "testapp_author" in output
        assert "rows" in output
        assert "Table" in output

    def test_basic_no_display(self):
        output = Author.objects.all().pt_visual_explain(display=False)
        assert "testapp_author" in output
Ejemplo n.º 4
0
        VanillaAuthor.objects.create(name="pants")
        VanillaAuthor.objects.create(name="Beta")
        VanillaAuthor.objects.create(name="pants")

        bad_authors = VanillaAuthor.objects.filter(name="pants")

        self.assertEqual(bad_authors.count(), 2)

        with captured_stdout():
            for author in SmartIterator(bad_authors, report_progress=True):
                author.delete()

        self.assertEqual(bad_authors.count(), 0)


@skipUnless(have_program('pt-visual-explain'),
            "pt-visual-explain must be installed")
class VisualExplainTests(TransactionTestCase):

    def test_basic(self):
        with captured_stdout() as capture:
            Author.objects.all().pt_visual_explain()
        output = capture.getvalue()
        self.assertGreater(output, "")
        # Can't be too strict about the output since different database and pt-
        # visual-explain versions give different output
        self.assertIn("django_mysql_tests_author", output)
        self.assertIn("rows", output)
        self.assertIn("Table", output)

    def test_basic_no_display(self):
Ejemplo n.º 5
0
        VanillaAuthor.objects.create(name="pants")
        VanillaAuthor.objects.create(name="Beta")
        VanillaAuthor.objects.create(name="pants")

        bad_authors = VanillaAuthor.objects.filter(name="pants")

        assert bad_authors.count() == 2

        with captured_stdout():
            for author in SmartIterator(bad_authors, report_progress=True):
                author.delete()

        assert bad_authors.count() == 0


@skipUnless(have_program("pt-visual-explain"), "pt-visual-explain must be installed")
class VisualExplainTests(TestCase):
    def test_basic(self):
        with captured_stdout() as capture:
            Author.objects.all().pt_visual_explain()
        output = capture.getvalue()
        # Can't be too strict about the output since different database and pt-
        # visual-explain versions give different output
        assert "testapp_author" in output
        assert "rows" in output
        assert "Table" in output

    def test_basic_no_display(self):
        output = Author.objects.all().pt_visual_explain(display=False)
        assert "testapp_author" in output
        assert "rows" in output
Ejemplo n.º 6
0
        assert format_duration(1) == '1s'
        assert format_duration(30) == '30s'
        assert format_duration(59) == '59s'

    def test_minutes(self):
        assert format_duration(60) == '1m0s'
        assert format_duration(61) == '1m1s'
        assert format_duration(120) == '2m0s'
        assert format_duration(3599) == '59m59s'

    def test_hours(self):
        assert format_duration(3600) == '1h0m0s'
        assert format_duration(3601) == '1h0m1s'


@skipUnless(have_program('pt-fingerprint'),
            "pt-fingerprint must be installed")
class PTFingerprintTests(SimpleTestCase):

    def test_basic(self):
        assert pt_fingerprint('SELECT 5') == 'select ?'
        assert pt_fingerprint('SELECT 5;') == 'select ?'

    def test_long(self):
        query = """
            SELECT
                CONCAT(customer.last_name, ', ', customer.first_name)
                    AS customer,
                address.phone,
                film.title
            FROM rental
Ejemplo n.º 7
0
        assert format_duration(1) == '1s'
        assert format_duration(30) == '30s'
        assert format_duration(59) == '59s'

    def test_minutes(self):
        assert format_duration(60) == '1m0s'
        assert format_duration(61) == '1m1s'
        assert format_duration(120) == '2m0s'
        assert format_duration(3599) == '59m59s'

    def test_hours(self):
        assert format_duration(3600) == '1h0m0s'
        assert format_duration(3601) == '1h0m1s'


@skipUnless(have_program('pt-fingerprint'), "pt-fingerprint must be installed")
class PTFingerprintTests(SimpleTestCase):
    def test_basic(self):
        assert pt_fingerprint('SELECT 5') == 'select ?'
        assert pt_fingerprint('SELECT 5;') == 'select ?'

    def test_long(self):
        query = """
            SELECT
                CONCAT(customer.last_name, ', ', customer.first_name)
                    AS customer,
                address.phone,
                film.title
            FROM rental
                INNER JOIN customer
                    ON rental.customer_id = customer.customer_id
Ejemplo n.º 8
0
        assert format_duration(1) == '1s'
        assert format_duration(30) == '30s'
        assert format_duration(59) == '59s'

    def test_minutes(self):
        assert format_duration(60) == '1m0s'
        assert format_duration(61) == '1m1s'
        assert format_duration(120) == '2m0s'
        assert format_duration(3599) == '59m59s'

    def test_hours(self):
        assert format_duration(3600) == '1h0m0s'
        assert format_duration(3601) == '1h0m1s'


@skipUnless(have_program('pt-fingerprint'),
            "pt-fingerprint must be installed")
class PTFingerprintTests(SimpleTestCase):

    def test_basic(self):
        assert pt_fingerprint('SELECT 5') == 'select ?'
        assert pt_fingerprint('SELECT 5;') == 'select ?'

    def test_long(self):
        query = """
            SELECT
                CONCAT(customer.last_name, ', ', customer.first_name)
                    AS customer,
                address.phone,
                film.title
            FROM rental
Ejemplo n.º 9
0
        VanillaAuthor.objects.create(name="pants")
        VanillaAuthor.objects.create(name="Beta")
        VanillaAuthor.objects.create(name="pants")

        bad_authors = VanillaAuthor.objects.filter(name="pants")

        assert bad_authors.count() == 2

        with captured_stdout():
            for author in SmartIterator(bad_authors, report_progress=True):
                author.delete()

        assert bad_authors.count() == 0


@skipUnless(have_program("pt-visual-explain"),
            "pt-visual-explain must be installed")
class VisualExplainTests(TestCase):
    def test_basic(self):
        with captured_stdout() as capture:
            Author.objects.all().pt_visual_explain()
        output = capture.getvalue()
        # Can't be too strict about the output since different database and pt-
        # visual-explain versions give different output
        assert "testapp_author" in output
        assert "rows" in output
        assert "Table" in output

    def test_basic_no_display(self):
        output = Author.objects.all().pt_visual_explain(display=False)
        assert "testapp_author" in output