piccolo 1.5.2__py3-none-any.whl → 1.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- piccolo/__init__.py +1 -1
- piccolo/columns/base.py +31 -40
- piccolo/columns/column_types.py +37 -13
- piccolo/columns/m2m.py +16 -6
- piccolo/columns/readable.py +9 -7
- piccolo/engine/sqlite.py +171 -57
- piccolo/query/__init__.py +1 -4
- piccolo/query/functions/__init__.py +16 -0
- piccolo/query/functions/aggregate.py +179 -0
- piccolo/query/functions/base.py +21 -0
- piccolo/query/functions/string.py +73 -0
- piccolo/query/methods/__init__.py +18 -1
- piccolo/query/methods/count.py +3 -3
- piccolo/query/methods/delete.py +1 -1
- piccolo/query/methods/exists.py +1 -1
- piccolo/query/methods/objects.py +1 -1
- piccolo/query/methods/select.py +17 -232
- piccolo/query/methods/update.py +1 -1
- piccolo/query/mixins.py +9 -2
- piccolo/querystring.py +101 -13
- piccolo/table.py +8 -24
- {piccolo-1.5.2.dist-info → piccolo-1.7.0.dist-info}/METADATA +1 -1
- {piccolo-1.5.2.dist-info → piccolo-1.7.0.dist-info}/RECORD +30 -25
- tests/columns/test_array.py +89 -2
- tests/query/test_functions.py +102 -0
- tests/table/test_select.py +2 -9
- {piccolo-1.5.2.dist-info → piccolo-1.7.0.dist-info}/LICENSE +0 -0
- {piccolo-1.5.2.dist-info → piccolo-1.7.0.dist-info}/WHEEL +0 -0
- {piccolo-1.5.2.dist-info → piccolo-1.7.0.dist-info}/entry_points.txt +0 -0
- {piccolo-1.5.2.dist-info → piccolo-1.7.0.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,10 @@
|
|
1
|
-
piccolo/__init__.py,sha256=
|
1
|
+
piccolo/__init__.py,sha256=h4xA2N06XGCcrqnSQbI2FfqW4dGycKVDmFXCAklesxA,22
|
2
2
|
piccolo/custom_types.py,sha256=7HMQAze-5mieNLfbQ5QgbRQgR2abR7ol0qehv2SqROY,604
|
3
3
|
piccolo/main.py,sha256=1VsFV67FWTUikPTysp64Fmgd9QBVa_9wcwKfwj2UCEA,5117
|
4
4
|
piccolo/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
-
piccolo/querystring.py,sha256=
|
5
|
+
piccolo/querystring.py,sha256=6uxfoCk7sj6bs_mDNV8W4ScgdG-h5wl1Y9HMlVW2abM,8671
|
6
6
|
piccolo/schema.py,sha256=aWPuZxEulgBRD5NTqKN-RAZchxu-PoIrn0iFrWGZuq4,7731
|
7
|
-
piccolo/table.py,sha256=
|
7
|
+
piccolo/table.py,sha256=DJT8jTgirPpzkydjSzaCgcG0DiC75XRtW_xtFqTyg80,49457
|
8
8
|
piccolo/table_reflection.py,sha256=jrN1nHerDJ4tU09GtNN3hz7ap-7rXnSUjljFO6LB2H0,7094
|
9
9
|
piccolo/apps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
piccolo/apps/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -115,13 +115,13 @@ piccolo/apps/user/piccolo_migrations/2020-06-11T21-38-55.py,sha256=JG_LFPrEljnSE
|
|
115
115
|
piccolo/apps/user/piccolo_migrations/2021-04-30T16-14-15.py,sha256=Y_Dj4ROSxjnPsRDqcnpWeyk8UpF8c80T08_O2uq-GoA,1219
|
116
116
|
piccolo/apps/user/piccolo_migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
117
117
|
piccolo/columns/__init__.py,sha256=OYhO_n9anMiU9nL-K6ATq9FhAtm8RyMpqYQ7fTVbhxI,1120
|
118
|
-
piccolo/columns/base.py,sha256=
|
118
|
+
piccolo/columns/base.py,sha256=XUhhx-wNc6nBPd39VIYuNfFERTaFzow9SHGfZjJ2YC0,31288
|
119
119
|
piccolo/columns/choices.py,sha256=-HNQuk9vMmVZIPZ5PMeXGTfr23o4nzKPSAkvcG1k0y8,723
|
120
|
-
piccolo/columns/column_types.py,sha256=
|
120
|
+
piccolo/columns/column_types.py,sha256=CzbNnP_VWvz6_r4aaRcMHiHZOaWHeq5IGaN8WJ7JGPA,81685
|
121
121
|
piccolo/columns/combination.py,sha256=vMXC2dfY7pvnCFhsT71XFVyb4gdQzfRsCMaiduu04Ss,6900
|
122
122
|
piccolo/columns/indexes.py,sha256=NfNok3v_791jgDlN28KmhP9ZCjl6031BXmjxV3ovXJk,372
|
123
|
-
piccolo/columns/m2m.py,sha256=
|
124
|
-
piccolo/columns/readable.py,sha256=
|
123
|
+
piccolo/columns/m2m.py,sha256=vRJZqBcBP3TQ9Mmb7UEqTgg0QoxIIjIu6JfGLAi4X8Q,14595
|
124
|
+
piccolo/columns/readable.py,sha256=hganxUPfIK5ZXn-qgteBxsOJfBJucgr9U0QLsLFYcuI,1562
|
125
125
|
piccolo/columns/reference.py,sha256=FqE9rpMBMwNNkKXR3Wi4ce-fyT2Vh4KM8YpdC21s6gg,3574
|
126
126
|
piccolo/columns/defaults/__init__.py,sha256=7hpB13baEJgc1zbZjRKDFr-5hltxM2VGj8KnKfOiS8c,145
|
127
127
|
piccolo/columns/defaults/base.py,sha256=kxh5jgU9G1zpcncmqISZgwMeHnNPBgNCvuqPPQYO_zs,1854
|
@@ -144,27 +144,31 @@ piccolo/engine/cockroach.py,sha256=7anXR3JPpGuR6-OpDLHM0FxKZhjuTvbRUuZV6fv9lXU,1
|
|
144
144
|
piccolo/engine/exceptions.py,sha256=X8xZiTF-L9PIqFT-KDXnv1jFIIOZMF8fYK692chttJE,44
|
145
145
|
piccolo/engine/finder.py,sha256=GjzBNtzRzH79fjtRn7OI3nZiOXE8JfoQWAvHVPrPNx4,507
|
146
146
|
piccolo/engine/postgres.py,sha256=zUY6x52QrZ8waiqEUuqlVFiXyzAXrsFi3PY5EJnv3DM,18276
|
147
|
-
piccolo/engine/sqlite.py,sha256=
|
148
|
-
piccolo/query/__init__.py,sha256=
|
147
|
+
piccolo/engine/sqlite.py,sha256=edwACs4RWsbzgoozBJRN5l9_Vq4nCMefRRLzuZYsF7M,25033
|
148
|
+
piccolo/query/__init__.py,sha256=bcsMV4813rMRAIqGv4DxI4eyO4FmpXkDv9dfTk5pt3A,699
|
149
149
|
piccolo/query/base.py,sha256=G8Mwz0GcHY4Xs5Co9ubCNMI-3orfOsDdRDOnFRws7TU,15212
|
150
|
-
piccolo/query/mixins.py,sha256=
|
150
|
+
piccolo/query/mixins.py,sha256=1RyhORDRwTZF9m_2uEgc6sOSd2uViXivBAaFN8geq5g,21982
|
151
151
|
piccolo/query/proxy.py,sha256=Yq4jNc7IWJvdeO3u7_7iPyRy2WhVj8KsIUcIYHBIi9Q,1839
|
152
|
-
piccolo/query/
|
152
|
+
piccolo/query/functions/__init__.py,sha256=O_uuMZbwMVAe-ebr-COdc9QZtvUSQFomPa29me6cscs,266
|
153
|
+
piccolo/query/functions/aggregate.py,sha256=qSDb-2Of9FYXUKsdCsvaoPjGOefyhoxawWpA5oG3fQQ,4320
|
154
|
+
piccolo/query/functions/base.py,sha256=Go2bg2r7GaVoyyX-wTb80WEQmtiU4OFYWQlq9eQ6Zcc,478
|
155
|
+
piccolo/query/functions/string.py,sha256=srxsQJFS6L4gPvFjvuAFQj7QtnCF7X6YoJNKARR2XP0,1236
|
156
|
+
piccolo/query/methods/__init__.py,sha256=tm4gLeV_obDqpgnouVjFbGubbaoJcqm_cbNd4LPo48Q,622
|
153
157
|
piccolo/query/methods/alter.py,sha256=AI9YkJeip2EitrWJN_TDExXhA8HGAG3XuDz1NR-KirQ,16728
|
154
|
-
piccolo/query/methods/count.py,sha256=
|
158
|
+
piccolo/query/methods/count.py,sha256=Vxn_7Ry-rleC6OGRxh-cLbuEMsy1DNjAZJThGED-_do,1748
|
155
159
|
piccolo/query/methods/create.py,sha256=hJ-6VVsWczzKDH6fQRN1WmYhcitixuXJ-eNOuCo_JgM,2742
|
156
160
|
piccolo/query/methods/create_index.py,sha256=RV9yVHwPvfQCk-g6YpmUTKamgOj0uxWe8Zr97YHIPGo,2216
|
157
|
-
piccolo/query/methods/delete.py,sha256=
|
161
|
+
piccolo/query/methods/delete.py,sha256=3QNh8wsn2hUP1Ce9nz5ps1huU6ySHjyqkjdP-VYN-U8,2234
|
158
162
|
piccolo/query/methods/drop_index.py,sha256=SOX5wfm-Tbb5TrN6kaLRVHUWdEhyrmCQwF33JfWdtwE,1043
|
159
|
-
piccolo/query/methods/exists.py,sha256=
|
163
|
+
piccolo/query/methods/exists.py,sha256=lTMjtrFPFygZmaPV3sfQKXc3K0sVqJ2S6PDc3fRK6YQ,1203
|
160
164
|
piccolo/query/methods/indexes.py,sha256=J-QUqaBJwpgahskUH0Cu0Mq7zEKcfVAtDsUVIVX-C4c,943
|
161
165
|
piccolo/query/methods/insert.py,sha256=ssLJ_wn08KnOwwr7t-VILyn1P4hrvM63CfPIcAJWT5k,4701
|
162
|
-
piccolo/query/methods/objects.py,sha256=
|
166
|
+
piccolo/query/methods/objects.py,sha256=Kw0T1LB4qQkV5vQDKb6HxRw90qDUq6Fgp95_ayX6buo,11727
|
163
167
|
piccolo/query/methods/raw.py,sha256=VhYpCB52mZk4zqFTsqK5CHKTDGskUjISXTBV7UjohmA,600
|
164
168
|
piccolo/query/methods/refresh.py,sha256=P1Eo_HYU_L7kcGM_cvDDgyLi1boCXY7Pc4tv_eDAzvc,2769
|
165
|
-
piccolo/query/methods/select.py,sha256=
|
169
|
+
piccolo/query/methods/select.py,sha256=soeBlUXMKvKdmHOkur1O7SOnCpHjRD1tCD4W-fKrLdg,21053
|
166
170
|
piccolo/query/methods/table_exists.py,sha256=0yb3n6Jd2ovSBWlZ-gl00K4E7Jnbj7J8qAAX5d7hvNk,1259
|
167
|
-
piccolo/query/methods/update.py,sha256=
|
171
|
+
piccolo/query/methods/update.py,sha256=LfWqIXEl1aecc0rkVssTFmwyD6wXGhlKcTrUVhtlEsw,3705
|
168
172
|
piccolo/testing/__init__.py,sha256=pRFSqRInfx95AakOq54atmvqoB-ue073q2aR8u8zR40,83
|
169
173
|
piccolo/testing/model_builder.py,sha256=lVEiEe71xrH8SSjzFc2l0s-VaCXHeg9Bo5oAYOEbLrI,6545
|
170
174
|
piccolo/testing/random_builder.py,sha256=0LkGpanQ7P1R82gLIMQyK9cm1LdZkPvxbShTEf3jeH4,2128
|
@@ -237,7 +241,7 @@ tests/apps/user/commands/test_change_permissions.py,sha256=uVKEiT1EKot3VA2TDETdQ
|
|
237
241
|
tests/apps/user/commands/test_create.py,sha256=iJ3Tti62rHwvdcTwNXrc5JPam6vR1qxKRdMN456vm3o,2250
|
238
242
|
tests/apps/user/commands/test_list.py,sha256=ipPfGdW6fH7q-Jc7JcYUvlioGmH9GQU0WImZGC2m-XQ,2840
|
239
243
|
tests/columns/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
240
|
-
tests/columns/test_array.py,sha256=
|
244
|
+
tests/columns/test_array.py,sha256=Kd8yy3C4cXJIgutY-cv0MrE4mvgr52qqVUdkcazW_uI,9298
|
241
245
|
tests/columns/test_base.py,sha256=CTqCNcrqAJTjLXe3MCZgTczrmB3jcVRcOpU4FilpLoQ,3918
|
242
246
|
tests/columns/test_bigint.py,sha256=a0B4y1H02ww5qaW574X2lyenbY6o29ztOhiaqybPC0c,1149
|
243
247
|
tests/columns/test_boolean.py,sha256=kDESp6FnRtSZhuqIu0dBRwKMSpS5TFbbs3sz2MyZSs8,1720
|
@@ -291,6 +295,7 @@ tests/query/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
291
295
|
tests/query/test_await.py,sha256=imGazmG0l4qilveNPwsxvYQogFJtos4YB8N9iggPEFU,412
|
292
296
|
tests/query/test_camelcase.py,sha256=AcL2gZera1GfpVJNpuKuh5ZBosNCY_ezPWh6-duU5vU,1765
|
293
297
|
tests/query/test_freeze.py,sha256=p3iXqHzgV39YWlqzXtZvaDa7iKZaaaelOGX3UZ8CMf0,3887
|
298
|
+
tests/query/test_functions.py,sha256=_dYGLqsrYkWMxjb3MIlpsCbY1nC9n39IiRsrGhhrYJs,3182
|
294
299
|
tests/query/test_gather.py,sha256=okWANrBoh0Ut1RomWoffiWNpFqiITF6qti-Aa3uYtRk,730
|
295
300
|
tests/query/test_querystring.py,sha256=hHljfdnOTlwIMs-7Q2yP5YekYXTT2It-Q-3mP6T9e58,880
|
296
301
|
tests/query/test_slots.py,sha256=I9ZjAYqAJNSFAWg9UyAqy7bm-Z52KiyQ2C_yHk2qqqI,1010
|
@@ -323,7 +328,7 @@ tests/table/test_raw.py,sha256=9PTvYngQi41nYd5lKzkJdTqsEcwrdOXcvZjq-W26CwQ,1683
|
|
323
328
|
tests/table/test_ref.py,sha256=eYNRnYHzNMXuMbV3B1ca5EidpIg4500q6hr1ccuVaso,269
|
324
329
|
tests/table/test_refresh.py,sha256=ZXGLGHeMZcWnhZPB4eCasv1RkojPt6nUbxaE7WlyJbo,2804
|
325
330
|
tests/table/test_repr.py,sha256=uahz3_GffGQrf2mDE-4-Pu4AmSLBAyso6-9rbohCl58,446
|
326
|
-
tests/table/test_select.py,sha256
|
331
|
+
tests/table/test_select.py,sha256=jgeiahIlNFVijxYb3a54g1sJWVfH3llaYrsTBmdicrs,40390
|
327
332
|
tests/table/test_str.py,sha256=eztWNULcjARR1fr9X5n4tojhDNgDfatVyNHwuYrzHAo,1731
|
328
333
|
tests/table/test_table_exists.py,sha256=upv2e9UD32V2QZOShzmcw0reMqRbYiX_jxWx57p25jg,1082
|
329
334
|
tests/table/test_update.py,sha256=Cqi0xX3kEuJ0k-x_emPGB3arXuGWZ9e3CJ3HPFnw9Zw,20505
|
@@ -350,9 +355,9 @@ tests/utils/test_sql_values.py,sha256=vzxRmy16FfLZPH-sAQexBvsF9MXB8n4smr14qoEOS5
|
|
350
355
|
tests/utils/test_sync.py,sha256=9ytVo56y2vPQePvTeIi9lHIouEhWJbodl1TmzkGFrSo,799
|
351
356
|
tests/utils/test_table_reflection.py,sha256=SIzuat-IpcVj1GCFyOWKShI8YkhdOPPFH7qVrvfyPNE,3794
|
352
357
|
tests/utils/test_warnings.py,sha256=NvSC_cvJ6uZcwAGf1m-hLzETXCqprXELL8zg3TNLVMw,269
|
353
|
-
piccolo-1.
|
354
|
-
piccolo-1.
|
355
|
-
piccolo-1.
|
356
|
-
piccolo-1.
|
357
|
-
piccolo-1.
|
358
|
-
piccolo-1.
|
358
|
+
piccolo-1.7.0.dist-info/LICENSE,sha256=zFIpi-16uIJ420UMIG75NU0JbDBykvrdnXcj5U_EYBI,1059
|
359
|
+
piccolo-1.7.0.dist-info/METADATA,sha256=AIBs_jqCxL694qW6TwjwE0C4_LF_RqzaVCZ_-6Ag6po,5177
|
360
|
+
piccolo-1.7.0.dist-info/WHEEL,sha256=00yskusixUoUt5ob_CiUp6LsnN5lqzTJpoqOFg_FVIc,92
|
361
|
+
piccolo-1.7.0.dist-info/entry_points.txt,sha256=SJPHET4Fi1bN5F3WqcKkv9SClK3_F1I7m4eQjk6AFh0,46
|
362
|
+
piccolo-1.7.0.dist-info/top_level.txt,sha256=-SR74VGbk43VoPy1HH-mHm97yoGukLK87HE5kdBW6qM,24
|
363
|
+
piccolo-1.7.0.dist-info/RECORD,,
|
tests/columns/test_array.py
CHANGED
@@ -1,6 +1,15 @@
|
|
1
|
+
import datetime
|
1
2
|
from unittest import TestCase
|
2
3
|
|
3
|
-
from piccolo.columns.column_types import
|
4
|
+
from piccolo.columns.column_types import (
|
5
|
+
Array,
|
6
|
+
BigInt,
|
7
|
+
Date,
|
8
|
+
Integer,
|
9
|
+
Time,
|
10
|
+
Timestamp,
|
11
|
+
Timestamptz,
|
12
|
+
)
|
4
13
|
from piccolo.table import Table
|
5
14
|
from tests.base import engines_only, sqlite_only
|
6
15
|
|
@@ -22,7 +31,7 @@ class TestArrayDefault(TestCase):
|
|
22
31
|
|
23
32
|
class TestArray(TestCase):
|
24
33
|
"""
|
25
|
-
Make sure an Array column can be created, and
|
34
|
+
Make sure an Array column can be created, and works correctly.
|
26
35
|
"""
|
27
36
|
|
28
37
|
def setUp(self):
|
@@ -166,6 +175,84 @@ class TestArray(TestCase):
|
|
166
175
|
)
|
167
176
|
|
168
177
|
|
178
|
+
###############################################################################
|
179
|
+
# Date and time arrays
|
180
|
+
|
181
|
+
|
182
|
+
class DateTimeArrayTable(Table):
|
183
|
+
date = Array(Date())
|
184
|
+
time = Array(Time())
|
185
|
+
timestamp = Array(Timestamp())
|
186
|
+
timestamptz = Array(Timestamptz())
|
187
|
+
date_nullable = Array(Date(), null=True)
|
188
|
+
time_nullable = Array(Time(), null=True)
|
189
|
+
timestamp_nullable = Array(Timestamp(), null=True)
|
190
|
+
timestamptz_nullable = Array(Timestamptz(), null=True)
|
191
|
+
|
192
|
+
|
193
|
+
class TestDateTimeArray(TestCase):
|
194
|
+
"""
|
195
|
+
Make sure that data can be stored and retrieved when using arrays of
|
196
|
+
date / time / timestamp.
|
197
|
+
|
198
|
+
We have to serialise / deserialise it in a special way in SQLite, hence
|
199
|
+
the tests.
|
200
|
+
|
201
|
+
"""
|
202
|
+
|
203
|
+
def setUp(self):
|
204
|
+
DateTimeArrayTable.create_table().run_sync()
|
205
|
+
|
206
|
+
def tearDown(self):
|
207
|
+
DateTimeArrayTable.alter().drop_table().run_sync()
|
208
|
+
|
209
|
+
@engines_only("postgres", "sqlite")
|
210
|
+
def test_storage(self):
|
211
|
+
test_date = datetime.date(year=2024, month=1, day=1)
|
212
|
+
test_time = datetime.time(hour=12, minute=0)
|
213
|
+
test_timestamp = datetime.datetime(
|
214
|
+
year=2024, month=1, day=1, hour=12, minute=0
|
215
|
+
)
|
216
|
+
test_timestamptz = datetime.datetime(
|
217
|
+
year=2024,
|
218
|
+
month=1,
|
219
|
+
day=1,
|
220
|
+
hour=12,
|
221
|
+
minute=0,
|
222
|
+
tzinfo=datetime.timezone.utc,
|
223
|
+
)
|
224
|
+
|
225
|
+
DateTimeArrayTable(
|
226
|
+
{
|
227
|
+
DateTimeArrayTable.date: [test_date],
|
228
|
+
DateTimeArrayTable.time: [test_time],
|
229
|
+
DateTimeArrayTable.timestamp: [test_timestamp],
|
230
|
+
DateTimeArrayTable.timestamptz: [test_timestamptz],
|
231
|
+
DateTimeArrayTable.date_nullable: None,
|
232
|
+
DateTimeArrayTable.time_nullable: None,
|
233
|
+
DateTimeArrayTable.timestamp_nullable: None,
|
234
|
+
DateTimeArrayTable.timestamptz_nullable: None,
|
235
|
+
}
|
236
|
+
).save().run_sync()
|
237
|
+
|
238
|
+
row = DateTimeArrayTable.objects().first().run_sync()
|
239
|
+
assert row is not None
|
240
|
+
|
241
|
+
self.assertListEqual(row.date, [test_date])
|
242
|
+
self.assertListEqual(row.time, [test_time])
|
243
|
+
self.assertListEqual(row.timestamp, [test_timestamp])
|
244
|
+
self.assertListEqual(row.timestamptz, [test_timestamptz])
|
245
|
+
|
246
|
+
self.assertIsNone(row.date_nullable)
|
247
|
+
self.assertIsNone(row.time_nullable)
|
248
|
+
self.assertIsNone(row.timestamp_nullable)
|
249
|
+
self.assertIsNone(row.timestamptz_nullable)
|
250
|
+
|
251
|
+
|
252
|
+
###############################################################################
|
253
|
+
# Nested arrays
|
254
|
+
|
255
|
+
|
169
256
|
class NestedArrayTable(Table):
|
170
257
|
value = Array(base_column=Array(base_column=BigInt()))
|
171
258
|
|
@@ -0,0 +1,102 @@
|
|
1
|
+
from unittest import TestCase
|
2
|
+
|
3
|
+
from piccolo.query.functions.string import Reverse, Upper
|
4
|
+
from piccolo.querystring import QueryString
|
5
|
+
from piccolo.table import create_db_tables_sync, drop_db_tables_sync
|
6
|
+
from tests.base import engines_skip
|
7
|
+
from tests.example_apps.music.tables import Band, Manager
|
8
|
+
|
9
|
+
|
10
|
+
class FunctionTest(TestCase):
|
11
|
+
tables = (Band, Manager)
|
12
|
+
|
13
|
+
def setUp(self) -> None:
|
14
|
+
create_db_tables_sync(*self.tables)
|
15
|
+
|
16
|
+
manager = Manager({Manager.name: "Guido"})
|
17
|
+
manager.save().run_sync()
|
18
|
+
|
19
|
+
band = Band({Band.name: "Pythonistas", Band.manager: manager})
|
20
|
+
band.save().run_sync()
|
21
|
+
|
22
|
+
def tearDown(self) -> None:
|
23
|
+
drop_db_tables_sync(*self.tables)
|
24
|
+
|
25
|
+
|
26
|
+
class TestUpperFunction(FunctionTest):
|
27
|
+
|
28
|
+
def test_column(self):
|
29
|
+
"""
|
30
|
+
Make sure we can uppercase a column's value.
|
31
|
+
"""
|
32
|
+
response = Band.select(Upper(Band.name)).run_sync()
|
33
|
+
self.assertListEqual(response, [{"upper": "PYTHONISTAS"}])
|
34
|
+
|
35
|
+
def test_alias(self):
|
36
|
+
response = Band.select(Upper(Band.name, alias="name")).run_sync()
|
37
|
+
self.assertListEqual(response, [{"name": "PYTHONISTAS"}])
|
38
|
+
|
39
|
+
def test_joined_column(self):
|
40
|
+
"""
|
41
|
+
Make sure we can uppercase a column's value from a joined table.
|
42
|
+
"""
|
43
|
+
response = Band.select(Upper(Band.manager._.name)).run_sync()
|
44
|
+
self.assertListEqual(response, [{"upper": "GUIDO"}])
|
45
|
+
|
46
|
+
|
47
|
+
@engines_skip("sqlite")
|
48
|
+
class TestNested(FunctionTest):
|
49
|
+
"""
|
50
|
+
Skip the the test for SQLite, as it doesn't support ``Reverse``.
|
51
|
+
"""
|
52
|
+
|
53
|
+
def test_nested(self):
|
54
|
+
"""
|
55
|
+
Make sure we can nest functions.
|
56
|
+
"""
|
57
|
+
response = Band.select(Upper(Reverse(Band.name))).run_sync()
|
58
|
+
self.assertListEqual(response, [{"upper": "SATSINOHTYP"}])
|
59
|
+
|
60
|
+
def test_nested_with_joined_column(self):
|
61
|
+
"""
|
62
|
+
Make sure nested functions can be used on a column from a joined table.
|
63
|
+
"""
|
64
|
+
response = Band.select(Upper(Reverse(Band.manager._.name))).run_sync()
|
65
|
+
self.assertListEqual(response, [{"upper": "ODIUG"}])
|
66
|
+
|
67
|
+
def test_nested_within_querystring(self):
|
68
|
+
"""
|
69
|
+
If we wrap a function in a custom QueryString - make sure the columns
|
70
|
+
are still accessible, so joins are successful.
|
71
|
+
"""
|
72
|
+
response = Band.select(
|
73
|
+
QueryString("CONCAT({}, '!')", Upper(Band.manager._.name)),
|
74
|
+
).run_sync()
|
75
|
+
|
76
|
+
self.assertListEqual(response, [{"concat": "GUIDO!"}])
|
77
|
+
|
78
|
+
|
79
|
+
class TestWhereClause(FunctionTest):
|
80
|
+
|
81
|
+
def test_where(self):
|
82
|
+
"""
|
83
|
+
Make sure where clauses work with functions.
|
84
|
+
"""
|
85
|
+
response = (
|
86
|
+
Band.select(Band.name)
|
87
|
+
.where(Upper(Band.name) == "PYTHONISTAS")
|
88
|
+
.run_sync()
|
89
|
+
)
|
90
|
+
self.assertListEqual(response, [{"name": "Pythonistas"}])
|
91
|
+
|
92
|
+
def test_where_with_joined_column(self):
|
93
|
+
"""
|
94
|
+
Make sure where clauses work with functions, when a joined column is
|
95
|
+
used.
|
96
|
+
"""
|
97
|
+
response = (
|
98
|
+
Band.select(Band.name)
|
99
|
+
.where(Upper(Band.manager._.name) == "GUIDO")
|
100
|
+
.run_sync()
|
101
|
+
)
|
102
|
+
self.assertListEqual(response, [{"name": "Pythonistas"}])
|
tests/table/test_select.py
CHANGED
@@ -7,7 +7,8 @@ from piccolo.apps.user.tables import BaseUser
|
|
7
7
|
from piccolo.columns import Date, Varchar
|
8
8
|
from piccolo.columns.combination import WhereRaw
|
9
9
|
from piccolo.query import OrderByRaw
|
10
|
-
from piccolo.query.
|
10
|
+
from piccolo.query.functions.aggregate import Avg, Count, Max, Min, Sum
|
11
|
+
from piccolo.query.methods.select import SelectRaw
|
11
12
|
from piccolo.query.mixins import DistinctOnError
|
12
13
|
from piccolo.table import Table, create_db_tables_sync, drop_db_tables_sync
|
13
14
|
from tests.base import (
|
@@ -927,14 +928,6 @@ class TestSelect(DBTestCase):
|
|
927
928
|
self.assertEqual(float(response["popularity_avg"]), 1003.3333333333334)
|
928
929
|
self.assertEqual(response["popularity_sum"], 3010)
|
929
930
|
|
930
|
-
def test_avg_validation(self):
|
931
|
-
with self.assertRaises(ValueError):
|
932
|
-
Band.select(Avg(Band.name)).run_sync()
|
933
|
-
|
934
|
-
def test_sum_validation(self):
|
935
|
-
with self.assertRaises(ValueError):
|
936
|
-
Band.select(Sum(Band.name)).run_sync()
|
937
|
-
|
938
931
|
def test_columns(self):
|
939
932
|
"""
|
940
933
|
Make sure the colums method can be used to specify which columns to
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|