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.
@@ -1,10 +1,10 @@
1
- piccolo/__init__.py,sha256=f_QOyG9IZDoR-FbyiLGFmbPuPBY4CR9EZgrInXOyPUo,22
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=YZkenGtG4mVSUdM7-zZXedxgIzXOnNOZf16AIqMr2n0,5863
5
+ piccolo/querystring.py,sha256=6uxfoCk7sj6bs_mDNV8W4ScgdG-h5wl1Y9HMlVW2abM,8671
6
6
  piccolo/schema.py,sha256=aWPuZxEulgBRD5NTqKN-RAZchxu-PoIrn0iFrWGZuq4,7731
7
- piccolo/table.py,sha256=w582fj4V66e-EYbF5PPO4TWYCOdIzzylPsc4rNWhPEs,50001
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=7ZcqdJc1GuqmVPDHJlEkCHnEIKkXms0BlkS4fLIx80E,31620
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=REqafGESK3Zu8YbuCHM2v3R_KC-2OjGZs7D7VppH2KM,81013
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=BtcMM2FG7B442DifrbPxCNh2Wa4ZOQ-4ezEWYD0trVg,14365
124
- piccolo/columns/readable.py,sha256=vKIEc_vWxKo4GSPOeJZz-q5a1i4DNaoBcCNG_i_2OSA,1485
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=h5RrrDqy-28ck8L9SkLURfZWFSTcVdojTLDt1w8cTgk,22099
148
- piccolo/query/__init__.py,sha256=1R0cRo8xoycUTFbSZzmW5rndH-wW4DDqsWJQgTELiWU,683
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=3oFksbYSaNGz_F7XJRhTTMHK4Pdf8-FUfDMpdy7rsNM,21639
150
+ piccolo/query/mixins.py,sha256=1RyhORDRwTZF9m_2uEgc6sOSd2uViXivBAaFN8geq5g,21982
151
151
  piccolo/query/proxy.py,sha256=Yq4jNc7IWJvdeO3u7_7iPyRy2WhVj8KsIUcIYHBIi9Q,1839
152
- piccolo/query/methods/__init__.py,sha256=_PfGUdOd6AsKq1sqXeZUHhESHE-e1cNpwFr8Lyz7QoY,421
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=vSwn52IG0wlhPC6L-jYVlCsD4BPb2EkGHGwWn7z7gH4,1717
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=c4LO6-sGKfX-pi1nTZPC3aKvevgKWXuO28sFetbQ7WY,2212
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=LAeWpGKEMYZJeNGEcxbucxWDxAjn84jduNz2ZjzukPc,1181
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=4QFyK03sa0RXIvNCr8cl2RpvpxuO6DVeJ1vxGNwBNLM,11705
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=qP-EnhdcuQOmOQ_ADnnYvA4OFSnmU7avCiQ8yoP5OHs,26883
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=K0sq7XlIDr2mw5CwCvD4s9-jLcpYG6MI2hGScRGmdPc,3683
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=R6dnUBGcMHi5pVhczI4ydWpXsu2FqRASu6KtkhDWfZo,6660
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=-DoQ0mvAn4HnQl7BMBOp7KKJFZoF74qPWUc8Kzwklwg,40607
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.5.2.dist-info/LICENSE,sha256=zFIpi-16uIJ420UMIG75NU0JbDBykvrdnXcj5U_EYBI,1059
354
- piccolo-1.5.2.dist-info/METADATA,sha256=UFmYPf1eC7pCBuoNrO9uMFQaEbNuGC3tvNPT61-dS4I,5177
355
- piccolo-1.5.2.dist-info/WHEEL,sha256=00yskusixUoUt5ob_CiUp6LsnN5lqzTJpoqOFg_FVIc,92
356
- piccolo-1.5.2.dist-info/entry_points.txt,sha256=SJPHET4Fi1bN5F3WqcKkv9SClK3_F1I7m4eQjk6AFh0,46
357
- piccolo-1.5.2.dist-info/top_level.txt,sha256=-SR74VGbk43VoPy1HH-mHm97yoGukLK87HE5kdBW6qM,24
358
- piccolo-1.5.2.dist-info/RECORD,,
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,,
@@ -1,6 +1,15 @@
1
+ import datetime
1
2
  from unittest import TestCase
2
3
 
3
- from piccolo.columns.column_types import Array, BigInt, Integer
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 work correctly.
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"}])
@@ -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.methods.select import Avg, Count, Max, Min, SelectRaw, Sum
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