piccolo 1.7.0__py3-none-any.whl → 1.8.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 +4 -0
- piccolo/query/functions/__init__.py +2 -0
- piccolo/query/functions/aggregate.py +12 -12
- piccolo/query/functions/type_conversion.py +82 -0
- piccolo/querystring.py +12 -0
- {piccolo-1.7.0.dist-info → piccolo-1.8.0.dist-info}/METADATA +1 -1
- {piccolo-1.7.0.dist-info → piccolo-1.8.0.dist-info}/RECORD +15 -14
- tests/apps/migrations/auto/integration/test_migrations.py +28 -5
- tests/apps/migrations/auto/test_migration_manager.py +15 -15
- tests/query/test_functions.py +138 -2
- {piccolo-1.7.0.dist-info → piccolo-1.8.0.dist-info}/LICENSE +0 -0
- {piccolo-1.7.0.dist-info → piccolo-1.8.0.dist-info}/WHEEL +0 -0
- {piccolo-1.7.0.dist-info → piccolo-1.8.0.dist-info}/entry_points.txt +0 -0
- {piccolo-1.7.0.dist-info → piccolo-1.8.0.dist-info}/top_level.txt +0 -0
piccolo/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__VERSION__ = "1.
|
1
|
+
__VERSION__ = "1.8.0"
|
piccolo/columns/base.py
CHANGED
@@ -201,6 +201,10 @@ class ColumnMeta:
|
|
201
201
|
)
|
202
202
|
return self._table
|
203
203
|
|
204
|
+
@table.setter
|
205
|
+
def table(self, value: t.Type[Table]):
|
206
|
+
self._table = value
|
207
|
+
|
204
208
|
###########################################################################
|
205
209
|
|
206
210
|
# Used by Foreign Keys:
|
@@ -12,17 +12,17 @@ class Avg(Function):
|
|
12
12
|
|
13
13
|
.. code-block:: python
|
14
14
|
|
15
|
-
await Band.select(Avg(Band.popularity))
|
15
|
+
await Band.select(Avg(Band.popularity))
|
16
16
|
|
17
17
|
# We can use an alias. These two are equivalent:
|
18
18
|
|
19
19
|
await Band.select(
|
20
20
|
Avg(Band.popularity, alias="popularity_avg")
|
21
|
-
)
|
21
|
+
)
|
22
22
|
|
23
23
|
await Band.select(
|
24
24
|
Avg(Band.popularity).as_alias("popularity_avg")
|
25
|
-
)
|
25
|
+
)
|
26
26
|
|
27
27
|
"""
|
28
28
|
|
@@ -103,17 +103,17 @@ class Min(Function):
|
|
103
103
|
|
104
104
|
.. code-block:: python
|
105
105
|
|
106
|
-
await Band.select(Min(Band.popularity))
|
106
|
+
await Band.select(Min(Band.popularity))
|
107
107
|
|
108
108
|
# We can use an alias. These two are equivalent:
|
109
109
|
|
110
110
|
await Band.select(
|
111
111
|
Min(Band.popularity, alias="popularity_min")
|
112
|
-
)
|
112
|
+
)
|
113
113
|
|
114
114
|
await Band.select(
|
115
115
|
Min(Band.popularity).as_alias("popularity_min")
|
116
|
-
)
|
116
|
+
)
|
117
117
|
|
118
118
|
"""
|
119
119
|
|
@@ -128,17 +128,17 @@ class Max(Function):
|
|
128
128
|
|
129
129
|
await Band.select(
|
130
130
|
Max(Band.popularity)
|
131
|
-
)
|
131
|
+
)
|
132
132
|
|
133
133
|
# We can use an alias. These two are equivalent:
|
134
134
|
|
135
135
|
await Band.select(
|
136
136
|
Max(Band.popularity, alias="popularity_max")
|
137
|
-
)
|
137
|
+
)
|
138
138
|
|
139
139
|
await Band.select(
|
140
140
|
Max(Band.popularity).as_alias("popularity_max")
|
141
|
-
)
|
141
|
+
)
|
142
142
|
|
143
143
|
"""
|
144
144
|
|
@@ -153,17 +153,17 @@ class Sum(Function):
|
|
153
153
|
|
154
154
|
await Band.select(
|
155
155
|
Sum(Band.popularity)
|
156
|
-
)
|
156
|
+
)
|
157
157
|
|
158
158
|
# We can use an alias. These two are equivalent:
|
159
159
|
|
160
160
|
await Band.select(
|
161
161
|
Sum(Band.popularity, alias="popularity_sum")
|
162
|
-
)
|
162
|
+
)
|
163
163
|
|
164
164
|
await Band.select(
|
165
165
|
Sum(Band.popularity).as_alias("popularity_sum")
|
166
|
-
)
|
166
|
+
)
|
167
167
|
|
168
168
|
"""
|
169
169
|
|
@@ -0,0 +1,82 @@
|
|
1
|
+
import typing as t
|
2
|
+
|
3
|
+
from piccolo.columns.base import Column
|
4
|
+
from piccolo.querystring import QueryString
|
5
|
+
|
6
|
+
|
7
|
+
class Cast(QueryString):
|
8
|
+
def __init__(
|
9
|
+
self,
|
10
|
+
identifier: t.Union[Column, QueryString],
|
11
|
+
as_type: Column,
|
12
|
+
alias: t.Optional[str] = None,
|
13
|
+
):
|
14
|
+
"""
|
15
|
+
Cast a value to a different type. For example::
|
16
|
+
|
17
|
+
>>> from piccolo.query.functions import Cast
|
18
|
+
|
19
|
+
>>> await Concert.select(
|
20
|
+
... Cast(Concert.starts, Time(), "start_time")
|
21
|
+
... )
|
22
|
+
[{"start_time": datetime.time(19, 0)}]
|
23
|
+
|
24
|
+
:param identifier:
|
25
|
+
Identifies what is being converted (e.g. a column).
|
26
|
+
:param as_type:
|
27
|
+
The type to be converted to.
|
28
|
+
|
29
|
+
"""
|
30
|
+
# Make sure the identifier is a supported type.
|
31
|
+
|
32
|
+
if not isinstance(identifier, (Column, QueryString)):
|
33
|
+
raise ValueError(
|
34
|
+
"The identifier is an unsupported type - only Column and "
|
35
|
+
"QueryString instances are allowed."
|
36
|
+
)
|
37
|
+
|
38
|
+
#######################################################################
|
39
|
+
# Convert `as_type` to a string which can be used in the query.
|
40
|
+
|
41
|
+
if not isinstance(as_type, Column):
|
42
|
+
raise ValueError("The `as_type` value must be a Column instance.")
|
43
|
+
|
44
|
+
# We need to give the column a reference to a table, and hence
|
45
|
+
# the database engine, as the column type is sometimes dependent
|
46
|
+
# on which database is being used.
|
47
|
+
from piccolo.table import Table, create_table_class
|
48
|
+
|
49
|
+
table: t.Optional[t.Type[Table]] = None
|
50
|
+
|
51
|
+
if isinstance(identifier, Column):
|
52
|
+
table = identifier._meta.table
|
53
|
+
elif isinstance(identifier, QueryString):
|
54
|
+
table = (
|
55
|
+
identifier.columns[0]._meta.table
|
56
|
+
if identifier.columns
|
57
|
+
else None
|
58
|
+
)
|
59
|
+
|
60
|
+
as_type._meta.table = table or create_table_class("Table")
|
61
|
+
as_type_string = as_type.column_type
|
62
|
+
|
63
|
+
#######################################################################
|
64
|
+
# Preserve the original alias from the column.
|
65
|
+
|
66
|
+
if isinstance(identifier, Column):
|
67
|
+
alias = (
|
68
|
+
alias
|
69
|
+
or identifier._alias
|
70
|
+
or identifier._meta.get_default_alias()
|
71
|
+
)
|
72
|
+
|
73
|
+
#######################################################################
|
74
|
+
|
75
|
+
super().__init__(
|
76
|
+
f"CAST({{}} AS {as_type_string})",
|
77
|
+
identifier,
|
78
|
+
alias=alias,
|
79
|
+
)
|
80
|
+
|
81
|
+
|
82
|
+
__all__ = ("Cast",)
|
piccolo/querystring.py
CHANGED
@@ -270,6 +270,18 @@ class QueryString(Selectable):
|
|
270
270
|
def __sub__(self, value) -> QueryString:
|
271
271
|
return QueryString("{} - {}", self, value)
|
272
272
|
|
273
|
+
def __gt__(self, value) -> QueryString:
|
274
|
+
return QueryString("{} > {}", self, value)
|
275
|
+
|
276
|
+
def __ge__(self, value) -> QueryString:
|
277
|
+
return QueryString("{} >= {}", self, value)
|
278
|
+
|
279
|
+
def __lt__(self, value) -> QueryString:
|
280
|
+
return QueryString("{} < {}", self, value)
|
281
|
+
|
282
|
+
def __le__(self, value) -> QueryString:
|
283
|
+
return QueryString("{} <= {}", self, value)
|
284
|
+
|
273
285
|
def is_in(self, value) -> QueryString:
|
274
286
|
return QueryString("{} IN {}", self, value)
|
275
287
|
|
@@ -1,8 +1,8 @@
|
|
1
|
-
piccolo/__init__.py,sha256=
|
1
|
+
piccolo/__init__.py,sha256=mRuIID3n4xkvLnANZAYlJEC5QgpM7rOXi2uxp1_jzHg,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=Mn00hb4HGOe9MIR7WOhJ3qO1uNex21zj0m2heOeDvZk,9057
|
6
6
|
piccolo/schema.py,sha256=aWPuZxEulgBRD5NTqKN-RAZchxu-PoIrn0iFrWGZuq4,7731
|
7
7
|
piccolo/table.py,sha256=DJT8jTgirPpzkydjSzaCgcG0DiC75XRtW_xtFqTyg80,49457
|
8
8
|
piccolo/table_reflection.py,sha256=jrN1nHerDJ4tU09GtNN3hz7ap-7rXnSUjljFO6LB2H0,7094
|
@@ -115,7 +115,7 @@ 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=FuMLSplFuNoK919nkas2Fn4kZjmPLMmutc4cRtmLhyY,31378
|
119
119
|
piccolo/columns/choices.py,sha256=-HNQuk9vMmVZIPZ5PMeXGTfr23o4nzKPSAkvcG1k0y8,723
|
120
120
|
piccolo/columns/column_types.py,sha256=CzbNnP_VWvz6_r4aaRcMHiHZOaWHeq5IGaN8WJ7JGPA,81685
|
121
121
|
piccolo/columns/combination.py,sha256=vMXC2dfY7pvnCFhsT71XFVyb4gdQzfRsCMaiduu04Ss,6900
|
@@ -149,10 +149,11 @@ piccolo/query/__init__.py,sha256=bcsMV4813rMRAIqGv4DxI4eyO4FmpXkDv9dfTk5pt3A,699
|
|
149
149
|
piccolo/query/base.py,sha256=G8Mwz0GcHY4Xs5Co9ubCNMI-3orfOsDdRDOnFRws7TU,15212
|
150
150
|
piccolo/query/mixins.py,sha256=1RyhORDRwTZF9m_2uEgc6sOSd2uViXivBAaFN8geq5g,21982
|
151
151
|
piccolo/query/proxy.py,sha256=Yq4jNc7IWJvdeO3u7_7iPyRy2WhVj8KsIUcIYHBIi9Q,1839
|
152
|
-
piccolo/query/functions/__init__.py,sha256=
|
153
|
-
piccolo/query/functions/aggregate.py,sha256=
|
152
|
+
piccolo/query/functions/__init__.py,sha256=9ikQo6qPkCBaWSiuimEACWbYRk9KHoLboRsEC1VcSVw,312
|
153
|
+
piccolo/query/functions/aggregate.py,sha256=OdjDjr_zyD4S9UbrZ2C3V5mz4OT2sIfAFAdTGr4WL54,4248
|
154
154
|
piccolo/query/functions/base.py,sha256=Go2bg2r7GaVoyyX-wTb80WEQmtiU4OFYWQlq9eQ6Zcc,478
|
155
155
|
piccolo/query/functions/string.py,sha256=srxsQJFS6L4gPvFjvuAFQj7QtnCF7X6YoJNKARR2XP0,1236
|
156
|
+
piccolo/query/functions/type_conversion.py,sha256=OYbZc6TEk6b5yTwCMw2rmZ-UiQiUiWZOyxwMLzUjXwE,2583
|
156
157
|
piccolo/query/methods/__init__.py,sha256=tm4gLeV_obDqpgnouVjFbGubbaoJcqm_cbNd4LPo48Q,622
|
157
158
|
piccolo/query/methods/alter.py,sha256=AI9YkJeip2EitrWJN_TDExXhA8HGAG3XuDz1NR-KirQ,16728
|
158
159
|
piccolo/query/methods/count.py,sha256=Vxn_7Ry-rleC6OGRxh-cLbuEMsy1DNjAZJThGED-_do,1748
|
@@ -208,12 +209,12 @@ tests/apps/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
208
209
|
tests/apps/migrations/test_migration.py,sha256=JmPLtf2BCWX3Yofe0GQe40m8I_yWa_-3vk1lDfFDfIo,308
|
209
210
|
tests/apps/migrations/auto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
210
211
|
tests/apps/migrations/auto/test_diffable_table.py,sha256=bok3G9pwEYnE3AL6UG4iEHrVBZJQ_ovYCdKC3we5JVQ,2932
|
211
|
-
tests/apps/migrations/auto/test_migration_manager.py,sha256=
|
212
|
+
tests/apps/migrations/auto/test_migration_manager.py,sha256=NTNx4y5B0bMVLUR9BybX3zS4jxFI3_weLej8zOn3BkI,34798
|
212
213
|
tests/apps/migrations/auto/test_schema_differ.py,sha256=UdsaZisA02j15wr1bXkXD6Cqu3p0A23NwFQLXsJdQL4,19391
|
213
214
|
tests/apps/migrations/auto/test_schema_snapshot.py,sha256=ZyvGZqn3N3cwd-3S-FME5AJ8buDSHesw7yPIvY6mE5k,6196
|
214
215
|
tests/apps/migrations/auto/test_serialisation.py,sha256=EFkhES1w9h51UCamWrhxs3mf4I718ggeP7Yl5J_UID4,13548
|
215
216
|
tests/apps/migrations/auto/integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
216
|
-
tests/apps/migrations/auto/integration/test_migrations.py,sha256=
|
217
|
+
tests/apps/migrations/auto/integration/test_migrations.py,sha256=7rmATPGZNuchabUb2y5C9QMmv6XFChn5EHlYoRVChd4,46744
|
217
218
|
tests/apps/migrations/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
218
219
|
tests/apps/migrations/commands/test_base.py,sha256=NgHgVjNd3Hil9eODvW7Ic2D9muTa_grNaH3YpRFfR8I,1829
|
219
220
|
tests/apps/migrations/commands/test_check.py,sha256=hOX_sVk1nfCRfbQ8tJoFEUBFhih9O4QuQLHTp5TQaiY,630
|
@@ -295,7 +296,7 @@ tests/query/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
295
296
|
tests/query/test_await.py,sha256=imGazmG0l4qilveNPwsxvYQogFJtos4YB8N9iggPEFU,412
|
296
297
|
tests/query/test_camelcase.py,sha256=AcL2gZera1GfpVJNpuKuh5ZBosNCY_ezPWh6-duU5vU,1765
|
297
298
|
tests/query/test_freeze.py,sha256=p3iXqHzgV39YWlqzXtZvaDa7iKZaaaelOGX3UZ8CMf0,3887
|
298
|
-
tests/query/test_functions.py,sha256=
|
299
|
+
tests/query/test_functions.py,sha256=B_M-giOf1xGvdCaYgJdKWLSoV8vtTiRQtEyvL4-7eCY,6401
|
299
300
|
tests/query/test_gather.py,sha256=okWANrBoh0Ut1RomWoffiWNpFqiITF6qti-Aa3uYtRk,730
|
300
301
|
tests/query/test_querystring.py,sha256=hHljfdnOTlwIMs-7Q2yP5YekYXTT2It-Q-3mP6T9e58,880
|
301
302
|
tests/query/test_slots.py,sha256=I9ZjAYqAJNSFAWg9UyAqy7bm-Z52KiyQ2C_yHk2qqqI,1010
|
@@ -355,9 +356,9 @@ tests/utils/test_sql_values.py,sha256=vzxRmy16FfLZPH-sAQexBvsF9MXB8n4smr14qoEOS5
|
|
355
356
|
tests/utils/test_sync.py,sha256=9ytVo56y2vPQePvTeIi9lHIouEhWJbodl1TmzkGFrSo,799
|
356
357
|
tests/utils/test_table_reflection.py,sha256=SIzuat-IpcVj1GCFyOWKShI8YkhdOPPFH7qVrvfyPNE,3794
|
357
358
|
tests/utils/test_warnings.py,sha256=NvSC_cvJ6uZcwAGf1m-hLzETXCqprXELL8zg3TNLVMw,269
|
358
|
-
piccolo-1.
|
359
|
-
piccolo-1.
|
360
|
-
piccolo-1.
|
361
|
-
piccolo-1.
|
362
|
-
piccolo-1.
|
363
|
-
piccolo-1.
|
359
|
+
piccolo-1.8.0.dist-info/LICENSE,sha256=zFIpi-16uIJ420UMIG75NU0JbDBykvrdnXcj5U_EYBI,1059
|
360
|
+
piccolo-1.8.0.dist-info/METADATA,sha256=Uoe1LLvND5fOBdQKOSgFI1T047qzIlbICmwXV1zg7e4,5177
|
361
|
+
piccolo-1.8.0.dist-info/WHEEL,sha256=00yskusixUoUt5ob_CiUp6LsnN5lqzTJpoqOFg_FVIc,92
|
362
|
+
piccolo-1.8.0.dist-info/entry_points.txt,sha256=SJPHET4Fi1bN5F3WqcKkv9SClK3_F1I7m4eQjk6AFh0,46
|
363
|
+
piccolo-1.8.0.dist-info/top_level.txt,sha256=-SR74VGbk43VoPy1HH-mHm97yoGukLK87HE5kdBW6qM,24
|
364
|
+
piccolo-1.8.0.dist-info/RECORD,,
|
@@ -288,7 +288,12 @@ class TestMigrations(MigrationTestCase):
|
|
288
288
|
[
|
289
289
|
x.data_type == "text",
|
290
290
|
x.is_nullable == "NO",
|
291
|
-
x.column_default
|
291
|
+
x.column_default
|
292
|
+
in (
|
293
|
+
"''",
|
294
|
+
"''::text",
|
295
|
+
"'':::STRING",
|
296
|
+
),
|
292
297
|
]
|
293
298
|
),
|
294
299
|
)
|
@@ -461,6 +466,7 @@ class TestMigrations(MigrationTestCase):
|
|
461
466
|
in (
|
462
467
|
"now()",
|
463
468
|
"CURRENT_TIMESTAMP",
|
469
|
+
"current_timestamp()::TIMESTAMP",
|
464
470
|
"current_timestamp():::TIMESTAMPTZ::TIMESTAMP",
|
465
471
|
),
|
466
472
|
]
|
@@ -541,7 +547,11 @@ class TestMigrations(MigrationTestCase):
|
|
541
547
|
x.data_type == "interval",
|
542
548
|
x.is_nullable == "NO",
|
543
549
|
x.column_default
|
544
|
-
in (
|
550
|
+
in (
|
551
|
+
"'00:00:00'",
|
552
|
+
"'00:00:00'::interval",
|
553
|
+
"'00:00:00':::INTERVAL",
|
554
|
+
),
|
545
555
|
]
|
546
556
|
),
|
547
557
|
)
|
@@ -743,7 +753,12 @@ class TestMigrations(MigrationTestCase):
|
|
743
753
|
[
|
744
754
|
x.data_type == "jsonb",
|
745
755
|
x.is_nullable == "NO",
|
746
|
-
x.column_default
|
756
|
+
x.column_default
|
757
|
+
in (
|
758
|
+
"'{}'",
|
759
|
+
"'{}'::jsonb",
|
760
|
+
"'{}':::JSONB",
|
761
|
+
),
|
747
762
|
]
|
748
763
|
),
|
749
764
|
)
|
@@ -766,7 +781,11 @@ class TestMigrations(MigrationTestCase):
|
|
766
781
|
x.data_type == "character varying",
|
767
782
|
x.is_nullable == "NO",
|
768
783
|
x.column_default
|
769
|
-
in (
|
784
|
+
in (
|
785
|
+
"''",
|
786
|
+
"''::character varying",
|
787
|
+
"'':::STRING",
|
788
|
+
),
|
770
789
|
]
|
771
790
|
),
|
772
791
|
)
|
@@ -788,7 +807,11 @@ class TestMigrations(MigrationTestCase):
|
|
788
807
|
x.data_type == "character varying",
|
789
808
|
x.is_nullable == "NO",
|
790
809
|
x.column_default
|
791
|
-
in (
|
810
|
+
in (
|
811
|
+
"''",
|
812
|
+
"''::character varying",
|
813
|
+
"'':::STRING",
|
814
|
+
),
|
792
815
|
]
|
793
816
|
),
|
794
817
|
)
|
@@ -768,15 +768,15 @@ class TestMigrationManager(DBTestCase):
|
|
768
768
|
)
|
769
769
|
|
770
770
|
asyncio.run(manager.run())
|
771
|
-
self.
|
772
|
-
self._get_column_default(),
|
773
|
-
[
|
771
|
+
self.assertIn(
|
772
|
+
self._get_column_default()[0]["column_default"],
|
773
|
+
["'Unknown'", "'Unknown':::STRING"],
|
774
774
|
)
|
775
775
|
|
776
776
|
asyncio.run(manager.run(backwards=True))
|
777
|
-
self.
|
778
|
-
self._get_column_default(),
|
779
|
-
[
|
777
|
+
self.assertIn(
|
778
|
+
self._get_column_default()[0]["column_default"],
|
779
|
+
["''", "'':::STRING"],
|
780
780
|
)
|
781
781
|
|
782
782
|
@engines_only("postgres")
|
@@ -856,9 +856,9 @@ class TestMigrationManager(DBTestCase):
|
|
856
856
|
old_params={"default": None},
|
857
857
|
)
|
858
858
|
asyncio.run(manager_1.run())
|
859
|
-
self.
|
860
|
-
self._get_column_default(),
|
861
|
-
[
|
859
|
+
self.assertIn(
|
860
|
+
self._get_column_default()[0]["column_default"],
|
861
|
+
["'Mr Manager'", "'Mr Manager':::STRING"],
|
862
862
|
)
|
863
863
|
|
864
864
|
# Drop the default.
|
@@ -879,9 +879,9 @@ class TestMigrationManager(DBTestCase):
|
|
879
879
|
# And add it back once more to be sure.
|
880
880
|
manager_3 = manager_1
|
881
881
|
asyncio.run(manager_3.run())
|
882
|
-
self.
|
883
|
-
self._get_column_default(),
|
884
|
-
[
|
882
|
+
self.assertIn(
|
883
|
+
self._get_column_default()[0]["column_default"],
|
884
|
+
["'Mr Manager'", "'Mr Manager':::STRING"],
|
885
885
|
)
|
886
886
|
|
887
887
|
# Run them all backwards
|
@@ -892,9 +892,9 @@ class TestMigrationManager(DBTestCase):
|
|
892
892
|
)
|
893
893
|
|
894
894
|
asyncio.run(manager_2.run(backwards=True))
|
895
|
-
self.
|
896
|
-
self._get_column_default(),
|
897
|
-
[
|
895
|
+
self.assertIn(
|
896
|
+
self._get_column_default()[0]["column_default"],
|
897
|
+
["'Mr Manager'", "'Mr Manager':::STRING"],
|
898
898
|
)
|
899
899
|
|
900
900
|
asyncio.run(manager_1.run(backwards=True))
|
tests/query/test_functions.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
from unittest import TestCase
|
2
2
|
|
3
|
-
from piccolo.
|
3
|
+
from piccolo.columns import Integer, Text, Varchar
|
4
|
+
from piccolo.query.functions import Cast, Length, Reverse, Upper
|
4
5
|
from piccolo.querystring import QueryString
|
5
6
|
from piccolo.table import create_db_tables_sync, drop_db_tables_sync
|
6
7
|
from tests.base import engines_skip
|
@@ -16,7 +17,13 @@ class FunctionTest(TestCase):
|
|
16
17
|
manager = Manager({Manager.name: "Guido"})
|
17
18
|
manager.save().run_sync()
|
18
19
|
|
19
|
-
band = Band(
|
20
|
+
band = Band(
|
21
|
+
{
|
22
|
+
Band.name: "Pythonistas",
|
23
|
+
Band.manager: manager,
|
24
|
+
Band.popularity: 1000,
|
25
|
+
}
|
26
|
+
)
|
20
27
|
band.save().run_sync()
|
21
28
|
|
22
29
|
def tearDown(self) -> None:
|
@@ -100,3 +107,132 @@ class TestWhereClause(FunctionTest):
|
|
100
107
|
.run_sync()
|
101
108
|
)
|
102
109
|
self.assertListEqual(response, [{"name": "Pythonistas"}])
|
110
|
+
|
111
|
+
|
112
|
+
class TestCast(FunctionTest):
|
113
|
+
def test_varchar(self):
|
114
|
+
"""
|
115
|
+
Make sure that casting to ``Varchar`` works.
|
116
|
+
"""
|
117
|
+
response = Band.select(
|
118
|
+
Cast(
|
119
|
+
Band.popularity,
|
120
|
+
as_type=Varchar(),
|
121
|
+
)
|
122
|
+
).run_sync()
|
123
|
+
|
124
|
+
self.assertListEqual(
|
125
|
+
response,
|
126
|
+
[{"popularity": "1000"}],
|
127
|
+
)
|
128
|
+
|
129
|
+
def test_text(self):
|
130
|
+
"""
|
131
|
+
Make sure that casting to ``Text`` works.
|
132
|
+
"""
|
133
|
+
response = Band.select(
|
134
|
+
Cast(
|
135
|
+
Band.popularity,
|
136
|
+
as_type=Text(),
|
137
|
+
)
|
138
|
+
).run_sync()
|
139
|
+
|
140
|
+
self.assertListEqual(
|
141
|
+
response,
|
142
|
+
[{"popularity": "1000"}],
|
143
|
+
)
|
144
|
+
|
145
|
+
def test_integer(self):
|
146
|
+
"""
|
147
|
+
Make sure that casting to ``Integer`` works.
|
148
|
+
"""
|
149
|
+
Band.update({Band.name: "1111"}, force=True).run_sync()
|
150
|
+
|
151
|
+
response = Band.select(
|
152
|
+
Cast(
|
153
|
+
Band.name,
|
154
|
+
as_type=Integer(),
|
155
|
+
)
|
156
|
+
).run_sync()
|
157
|
+
|
158
|
+
self.assertListEqual(
|
159
|
+
response,
|
160
|
+
[{"name": 1111}],
|
161
|
+
)
|
162
|
+
|
163
|
+
def test_join(self):
|
164
|
+
"""
|
165
|
+
Make sure that casting works with joins.
|
166
|
+
"""
|
167
|
+
Manager.update({Manager.name: "1111"}, force=True).run_sync()
|
168
|
+
|
169
|
+
response = Band.select(
|
170
|
+
Band.name,
|
171
|
+
Cast(
|
172
|
+
Band.manager.name,
|
173
|
+
as_type=Integer(),
|
174
|
+
),
|
175
|
+
).run_sync()
|
176
|
+
|
177
|
+
self.assertListEqual(
|
178
|
+
response,
|
179
|
+
[
|
180
|
+
{
|
181
|
+
"name": "Pythonistas",
|
182
|
+
"manager.name": 1111,
|
183
|
+
}
|
184
|
+
],
|
185
|
+
)
|
186
|
+
|
187
|
+
def test_nested_inner(self):
|
188
|
+
"""
|
189
|
+
Make sure ``Cast`` can be passed into other functions.
|
190
|
+
"""
|
191
|
+
Band.update({Band.name: "1111"}, force=True).run_sync()
|
192
|
+
|
193
|
+
response = Band.select(
|
194
|
+
Length(
|
195
|
+
Cast(
|
196
|
+
Band.popularity,
|
197
|
+
as_type=Varchar(),
|
198
|
+
)
|
199
|
+
)
|
200
|
+
).run_sync()
|
201
|
+
|
202
|
+
self.assertListEqual(
|
203
|
+
response,
|
204
|
+
[{"length": 4}],
|
205
|
+
)
|
206
|
+
|
207
|
+
def test_nested_outer(self):
|
208
|
+
"""
|
209
|
+
Make sure a querystring can be passed into ``Cast`` (meaning it can be
|
210
|
+
nested).
|
211
|
+
"""
|
212
|
+
response = Band.select(
|
213
|
+
Cast(
|
214
|
+
Length(Band.name),
|
215
|
+
as_type=Varchar(),
|
216
|
+
alias="length",
|
217
|
+
)
|
218
|
+
).run_sync()
|
219
|
+
|
220
|
+
self.assertListEqual(
|
221
|
+
response,
|
222
|
+
[{"length": str(len("Pythonistas"))}],
|
223
|
+
)
|
224
|
+
|
225
|
+
def test_where_clause(self):
|
226
|
+
"""
|
227
|
+
Make sure ``Cast`` works in a where clause.
|
228
|
+
"""
|
229
|
+
response = (
|
230
|
+
Band.select(Band.name, Band.popularity)
|
231
|
+
.where(Cast(Band.popularity, Varchar()) == "1000")
|
232
|
+
.run_sync()
|
233
|
+
)
|
234
|
+
|
235
|
+
self.assertListEqual(
|
236
|
+
response,
|
237
|
+
[{"name": "Pythonistas", "popularity": 1000}],
|
238
|
+
)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|