forked from piccolo-orm/piccolo
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_freeze.py
More file actions
111 lines (95 loc) · 3.34 KB
/
test_freeze.py
File metadata and controls
111 lines (95 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import timeit
import typing as t
from dataclasses import dataclass
from piccolo.query.base import Query
from tests.base import DBTestCase, sqlite_only
from tests.example_apps.music.tables import Band
@dataclass
class QueryResponse:
query: Query
response: t.Any
class TestFreeze(DBTestCase):
def test_frozen_select_queries(self):
"""
Make sure a variety of select queries work as expected when frozen.
"""
self.insert_rows()
query_responses: t.List[QueryResponse] = [
QueryResponse(
query=(
Band.select(Band.name)
.order_by(Band.popularity, ascending=False)
.first()
.freeze()
),
response={"name": "Rustaceans"},
),
QueryResponse(
query=(
Band.select(Band.name)
.order_by(Band.popularity, ascending=False)
.freeze()
),
response=[
{"name": "Rustaceans"},
{"name": "Pythonistas"},
{"name": "CSharps"},
],
),
QueryResponse(
query=(
Band.select(Band.name)
.where(Band.name == "Pythonistas")
.freeze()
),
response=[{"name": "Pythonistas"}],
),
]
for query_response in query_responses:
result = query_response.query.run_sync()
self.assertEqual(result, query_response.response)
def test_output_clause(self):
"""
Make sure the output clause still works correctly with frozen queries.
"""
self.insert_rows()
result = (
Band.select(Band.name)
.where(Band.name == "Pythonistas")
.output(as_json=True)
.freeze()
.run_sync()
)
# Some JSON encoders have a space after the colons and some don't,
# so normalise them.
self.assertEqual(result.replace(" ", ""), '[{"name":"Pythonistas"}]')
@sqlite_only
def test_frozen_performance(self):
"""
The frozen query performance should exceed the non-frozen. If not,
there's a problem.
Only test this on SQLite, as the latency from the database itself
is more predictable than with Postgres, and the test runs quickly.
"""
iterations = 50
query = Band.select().where(Band.name == "Pythonistas").first()
query_duration = timeit.repeat(
lambda: query.run_sync(), repeat=iterations, number=1
)
frozen_query = query.freeze()
frozen_query_duration = timeit.repeat(
lambda: frozen_query.run_sync(), repeat=iterations, number=1
)
# Remove the outliers before comparing
self.assertTrue(
sum(sorted(query_duration)[5:-5])
> sum(sorted(frozen_query_duration)[5:-5])
)
def test_attribute_access(self):
"""
Once frozen, you shouldn't be able to call additional methods on the
query (for example `.where`).
"""
query = Band.select().freeze()
with self.assertRaises(AttributeError):
query.where(Band.name == "Pythonistas")