Skip to content

Commit 9d04e2f

Browse files
committed
add additional tests for frozen queries
1 parent 8866ef5 commit 9d04e2f

File tree

1 file changed

+54
-36
lines changed

1 file changed

+54
-36
lines changed

tests/query/test_freeze.py

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
from dataclasses import dataclass
22
import timeit
33
import typing as t
4-
from unittest.mock import patch
54

65
from piccolo.query.base import Query
76

8-
from tests.base import DBTestCase
7+
from tests.base import DBTestCase, sqlite_only
98
from tests.example_app.tables import Band
109

1110

@@ -52,43 +51,62 @@ def test_frozen_select_queries(self):
5251
),
5352
response=[{"name": "Pythonistas"}],
5453
),
55-
QueryResponse(
56-
query=(
57-
Band.select(Band.name)
58-
.where(Band.name == "Pythonistas")
59-
.output(as_json=True)
60-
.freeze()
61-
),
62-
response='[{"name":"Pythonistas"}]',
63-
),
6454
]
6555

6656
for query_response in query_responses:
6757
result = query_response.query.run_sync()
6858
self.assertEqual(result, query_response.response)
6959

70-
# def test_frozen_performance(self):
71-
# """
72-
# The frozen query performance should exceed the non-frozen. If not,
73-
# there's a problem.
74-
# """
75-
# with patch.object(Band._meta.db, "run_querystring"):
76-
# pass
77-
78-
# iterations = 50
79-
# query = Band.select().where(Band.name == "Pythonistas").first()
80-
# query_duration = timeit.timeit(
81-
# lambda: query.run_sync(), number=iterations
82-
# )
83-
84-
# # patch out the actual database call ... patching the engine is
85-
# # quite challenging ...
86-
87-
# frozen_query = query.freeze()
88-
# frozen_query_duration = timeit.timeit(
89-
# lambda: frozen_query.run_sync(), number=iterations
90-
# )
91-
# self.assertTrue(query_duration > frozen_query_duration)
92-
93-
# def test_attribute_access(self):
94-
# pass
60+
def test_output_clause(self):
61+
"""
62+
Make sure the output clause still works correctly with frozen queries.
63+
"""
64+
self.insert_rows()
65+
66+
result = (
67+
Band.select(Band.name)
68+
.where(Band.name == "Pythonistas")
69+
.output(as_json=True)
70+
.freeze()
71+
.run_sync()
72+
)
73+
# Some JSON encoders have a space after the colons and some don't,
74+
# so normalise them.
75+
self.assertEqual(result.replace(" ", ""), '[{"name":"Pythonistas"}]')
76+
77+
@sqlite_only
78+
def test_frozen_performance(self):
79+
"""
80+
The frozen query performance should exceed the non-frozen. If not,
81+
there's a problem.
82+
83+
Only test this on SQLite, as the latency from the database itself
84+
is more predictable than with Postgres, and the test runs quickly.
85+
86+
"""
87+
iterations = 50
88+
query = Band.select().where(Band.name == "Pythonistas").first()
89+
query_duration = timeit.repeat(
90+
lambda: query.run_sync(), repeat=iterations, number=1
91+
)
92+
93+
frozen_query = query.freeze()
94+
frozen_query_duration = timeit.repeat(
95+
lambda: frozen_query.run_sync(), repeat=iterations, number=1
96+
)
97+
98+
# Remove the outliers before comparing
99+
self.assertTrue(
100+
sum(sorted(query_duration)[5:-5])
101+
> sum(sorted(frozen_query_duration)[5:-5])
102+
)
103+
104+
def test_attribute_access(self):
105+
"""
106+
Once frozen, you shouldn't be able to call additional methods on the
107+
query (for example `.where`).
108+
"""
109+
query = Band.select().freeze()
110+
111+
with self.assertRaises(AttributeError):
112+
query.where(Band.name == "Pythonistas")

0 commit comments

Comments
 (0)