From 64c3ca9ed3474ae3dc1b8839902cbe2b448f8f3d Mon Sep 17 00:00:00 2001 From: Chris Chang Date: Tue, 4 Apr 2023 23:28:46 -0500 Subject: [PATCH] feat: collapse whitespace in multiline sql (#20) When used in conjunction with the colorizing output, only the first line of the SQL is colored. This is due to the logging filter assuming anything after the first line is a traceback; something to present in without color. Unfortunately, this breaks the intent of the SQL logging. Linebreaks in SQL logging aren't important. Getting rid of them doesn't hurt readability. In fact, even without the colorization, readability is improved because more lines fit on one screen. This does not catch all SQL with line breaks... I'll have to update the logic again later if I care. --- project_runpy/heidi.py | 5 ++++- test_project_runpy.py | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/project_runpy/heidi.py b/project_runpy/heidi.py index e698219..d52c1c5 100644 --- a/project_runpy/heidi.py +++ b/project_runpy/heidi.py @@ -114,7 +114,10 @@ class ReadableSqlFilter(logging.Filter): def filter(self, record): # https://github.com/django/django/blob/febe136d4c3310ec8901abecca3ea5ba2be3952c/django/db/backends/utils.py#L106-L131 - duration, sql, *__ = record.args + duration, sql, *record_args = record.args + if sql and "\n" in sql[:28]: + sql = " ".join(sql.strip().split()) + record.args = (duration, sql, *record_args) if not sql or "SELECT" not in sql[:28]: # WISHLIST what's the most performant way to see if 'SELECT' was # used? diff --git a/test_project_runpy.py b/test_project_runpy.py index 5cbb611..094ce58 100644 --- a/test_project_runpy.py +++ b/test_project_runpy.py @@ -176,6 +176,25 @@ def test_filter_formats_ignores_select_without_from(self): self.assertTrue(logging_filter.filter(record)) self.assertEqual(original_sql, record.args[1]) + def test_filter_collapses_multiline_sql(self): + long_sql = """ + (0.002) + SELECT VERSION(), + @@sql_mode, + @@default_storage_engine, + @@sql_auto_is_null, + @@lower_case_table_names, + CONVERT_TZ('2001-01-01 01:00:00', 'UTC', 'UTC') IS NOT NULL + ; args=None + """ + logging_filter = ReadableSqlFilter() + record = mock.MagicMock(args=(1.0, long_sql)) + self.assertIn("\n", record.args[1]) + + self.assertTrue(logging_filter.filter(record)) + + self.assertNotIn("\n", record.args[1]) + if __name__ == "__main__": unittest.main()