piccolo 1.8.0__py3-none-any.whl → 1.10.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/apps/fixtures/commands/load.py +1 -1
- piccolo/apps/migrations/auto/__init__.py +8 -0
- piccolo/apps/migrations/auto/migration_manager.py +2 -1
- piccolo/apps/migrations/commands/backwards.py +3 -1
- piccolo/apps/migrations/commands/base.py +1 -1
- piccolo/apps/migrations/commands/check.py +1 -1
- piccolo/apps/migrations/commands/clean.py +1 -1
- piccolo/apps/migrations/commands/forwards.py +3 -1
- piccolo/apps/migrations/commands/new.py +4 -2
- piccolo/apps/schema/commands/generate.py +2 -2
- piccolo/apps/shell/commands/run.py +1 -1
- piccolo/columns/base.py +55 -29
- piccolo/columns/column_types.py +28 -4
- piccolo/columns/defaults/base.py +6 -4
- piccolo/columns/defaults/date.py +9 -1
- piccolo/columns/defaults/interval.py +1 -0
- piccolo/columns/defaults/time.py +9 -1
- piccolo/columns/defaults/timestamp.py +1 -0
- piccolo/columns/defaults/uuid.py +1 -1
- piccolo/columns/m2m.py +7 -7
- piccolo/columns/operators/comparison.py +4 -0
- piccolo/conf/apps.py +9 -4
- piccolo/engine/base.py +69 -20
- piccolo/engine/cockroach.py +2 -3
- piccolo/engine/postgres.py +33 -19
- piccolo/engine/sqlite.py +27 -22
- piccolo/query/functions/__init__.py +5 -0
- piccolo/query/functions/math.py +48 -0
- piccolo/query/methods/create_index.py +1 -1
- piccolo/query/methods/drop_index.py +1 -1
- piccolo/query/methods/objects.py +7 -7
- piccolo/query/methods/select.py +13 -7
- piccolo/query/mixins.py +3 -10
- piccolo/querystring.py +18 -0
- piccolo/schema.py +20 -12
- piccolo/table.py +22 -21
- piccolo/utils/encoding.py +5 -3
- {piccolo-1.8.0.dist-info → piccolo-1.10.0.dist-info}/METADATA +1 -1
- {piccolo-1.8.0.dist-info → piccolo-1.10.0.dist-info}/RECORD +59 -52
- tests/apps/migrations/auto/integration/test_migrations.py +1 -1
- tests/columns/test_array.py +91 -19
- tests/columns/test_get_sql_value.py +66 -0
- tests/conf/test_apps.py +1 -1
- tests/engine/test_nested_transaction.py +2 -0
- tests/engine/test_transaction.py +1 -2
- tests/query/functions/__init__.py +0 -0
- tests/query/functions/base.py +34 -0
- tests/query/functions/test_functions.py +64 -0
- tests/query/functions/test_math.py +39 -0
- tests/query/functions/test_string.py +25 -0
- tests/query/functions/test_type_conversion.py +134 -0
- tests/query/test_querystring.py +136 -0
- tests/table/test_indexes.py +4 -2
- tests/utils/test_pydantic.py +70 -29
- tests/query/test_functions.py +0 -238
- {piccolo-1.8.0.dist-info → piccolo-1.10.0.dist-info}/LICENSE +0 -0
- {piccolo-1.8.0.dist-info → piccolo-1.10.0.dist-info}/WHEEL +0 -0
- {piccolo-1.8.0.dist-info → piccolo-1.10.0.dist-info}/entry_points.txt +0 -0
- {piccolo-1.8.0.dist-info → piccolo-1.10.0.dist-info}/top_level.txt +0 -0
tests/utils/test_pydantic.py
CHANGED
@@ -274,6 +274,7 @@ class TestUUIDColumn(TestCase):
|
|
274
274
|
# We'll also fetch it from the DB in case the database adapter's UUID
|
275
275
|
# is used.
|
276
276
|
ticket_from_db = Ticket.objects().first().run_sync()
|
277
|
+
assert ticket_from_db is not None
|
277
278
|
|
278
279
|
for ticket_ in (ticket, ticket_from_db):
|
279
280
|
json = pydantic_model(**ticket_.to_dict()).model_dump_json()
|
@@ -368,8 +369,8 @@ class TestJSONColumn(TestCase):
|
|
368
369
|
json_string = '{"code": 12345}'
|
369
370
|
|
370
371
|
model_instance = pydantic_model(meta=json_string, meta_b=json_string)
|
371
|
-
self.assertEqual(model_instance.meta, json_string)
|
372
|
-
self.assertEqual(model_instance.meta_b, json_string)
|
372
|
+
self.assertEqual(model_instance.meta, json_string) # type: ignore
|
373
|
+
self.assertEqual(model_instance.meta_b, json_string) # type: ignore
|
373
374
|
|
374
375
|
def test_deserialize_json(self):
|
375
376
|
class Movie(Table):
|
@@ -384,8 +385,8 @@ class TestJSONColumn(TestCase):
|
|
384
385
|
output = {"code": 12345}
|
385
386
|
|
386
387
|
model_instance = pydantic_model(meta=json_string, meta_b=json_string)
|
387
|
-
self.assertEqual(model_instance.meta, output)
|
388
|
-
self.assertEqual(model_instance.meta_b, output)
|
388
|
+
self.assertEqual(model_instance.meta, output) # type: ignore
|
389
|
+
self.assertEqual(model_instance.meta_b, output) # type: ignore
|
389
390
|
|
390
391
|
def test_validation(self):
|
391
392
|
class Movie(Table):
|
@@ -428,8 +429,8 @@ class TestJSONColumn(TestCase):
|
|
428
429
|
pydantic_model = create_pydantic_model(table=Movie)
|
429
430
|
movie = pydantic_model(meta=None, meta_b=None)
|
430
431
|
|
431
|
-
self.assertIsNone(movie.meta)
|
432
|
-
self.assertIsNone(movie.meta_b)
|
432
|
+
self.assertIsNone(movie.meta) # type: ignore
|
433
|
+
self.assertIsNone(movie.meta_b) # type: ignore
|
433
434
|
|
434
435
|
|
435
436
|
class TestExcludeColumns(TestCase):
|
@@ -490,7 +491,7 @@ class TestExcludeColumns(TestCase):
|
|
490
491
|
with self.assertRaises(ValueError):
|
491
492
|
create_pydantic_model(
|
492
493
|
Computer,
|
493
|
-
exclude_columns=("CPU",),
|
494
|
+
exclude_columns=("CPU",), # type: ignore
|
494
495
|
)
|
495
496
|
|
496
497
|
def test_invalid_column_different_table(self):
|
@@ -629,7 +630,10 @@ class TestNestedModel(TestCase):
|
|
629
630
|
|
630
631
|
#######################################################################
|
631
632
|
|
632
|
-
ManagerModel =
|
633
|
+
ManagerModel = t.cast(
|
634
|
+
t.Type[pydantic.BaseModel],
|
635
|
+
BandModel.model_fields["manager"].annotation,
|
636
|
+
)
|
633
637
|
self.assertTrue(issubclass(ManagerModel, pydantic.BaseModel))
|
634
638
|
self.assertEqual(
|
635
639
|
[i for i in ManagerModel.model_fields.keys()], ["name", "country"]
|
@@ -637,7 +641,10 @@ class TestNestedModel(TestCase):
|
|
637
641
|
|
638
642
|
#######################################################################
|
639
643
|
|
640
|
-
CountryModel =
|
644
|
+
CountryModel = t.cast(
|
645
|
+
t.Type[pydantic.BaseModel],
|
646
|
+
ManagerModel.model_fields["country"].annotation,
|
647
|
+
)
|
641
648
|
self.assertTrue(issubclass(CountryModel, pydantic.BaseModel))
|
642
649
|
self.assertEqual(
|
643
650
|
[i for i in CountryModel.model_fields.keys()], ["name"]
|
@@ -674,7 +681,10 @@ class TestNestedModel(TestCase):
|
|
674
681
|
|
675
682
|
BandModel = create_pydantic_model(table=Band, nested=(Band.manager,))
|
676
683
|
|
677
|
-
ManagerModel =
|
684
|
+
ManagerModel = t.cast(
|
685
|
+
t.Type[pydantic.BaseModel],
|
686
|
+
BandModel.model_fields["manager"].annotation,
|
687
|
+
)
|
678
688
|
self.assertTrue(issubclass(ManagerModel, pydantic.BaseModel))
|
679
689
|
self.assertEqual(
|
680
690
|
[i for i in ManagerModel.model_fields.keys()], ["name", "country"]
|
@@ -690,22 +700,29 @@ class TestNestedModel(TestCase):
|
|
690
700
|
# Test two levels deep
|
691
701
|
|
692
702
|
BandModel = create_pydantic_model(
|
693
|
-
table=Band, nested=(Band.manager.country,)
|
703
|
+
table=Band, nested=(Band.manager._.country,)
|
694
704
|
)
|
695
705
|
|
696
|
-
ManagerModel =
|
706
|
+
ManagerModel = t.cast(
|
707
|
+
t.Type[pydantic.BaseModel],
|
708
|
+
BandModel.model_fields["manager"].annotation,
|
709
|
+
)
|
697
710
|
self.assertTrue(issubclass(ManagerModel, pydantic.BaseModel))
|
698
711
|
self.assertEqual(
|
699
712
|
[i for i in ManagerModel.model_fields.keys()], ["name", "country"]
|
700
713
|
)
|
701
714
|
self.assertEqual(ManagerModel.__qualname__, "Band.manager")
|
702
715
|
|
703
|
-
AssistantManagerType =
|
704
|
-
|
705
|
-
|
716
|
+
AssistantManagerType = t.cast(
|
717
|
+
t.Type[pydantic.BaseModel],
|
718
|
+
BandModel.model_fields["assistant_manager"].annotation,
|
719
|
+
)
|
706
720
|
self.assertIs(AssistantManagerType, t.Optional[int])
|
707
721
|
|
708
|
-
CountryModel =
|
722
|
+
CountryModel = t.cast(
|
723
|
+
t.Type[pydantic.BaseModel],
|
724
|
+
ManagerModel.model_fields["country"].annotation,
|
725
|
+
)
|
709
726
|
self.assertTrue(issubclass(CountryModel, pydantic.BaseModel))
|
710
727
|
self.assertEqual(
|
711
728
|
[i for i in CountryModel.model_fields.keys()], ["name"]
|
@@ -716,13 +733,16 @@ class TestNestedModel(TestCase):
|
|
716
733
|
# Test three levels deep
|
717
734
|
|
718
735
|
ConcertModel = create_pydantic_model(
|
719
|
-
Concert, nested=(Concert.band_1.manager,)
|
736
|
+
Concert, nested=(Concert.band_1._.manager,)
|
720
737
|
)
|
721
738
|
|
722
739
|
VenueModel = ConcertModel.model_fields["venue"].annotation
|
723
740
|
self.assertIs(VenueModel, t.Optional[int])
|
724
741
|
|
725
|
-
BandModel =
|
742
|
+
BandModel = t.cast(
|
743
|
+
t.Type[pydantic.BaseModel],
|
744
|
+
ConcertModel.model_fields["band_1"].annotation,
|
745
|
+
)
|
726
746
|
self.assertTrue(issubclass(BandModel, pydantic.BaseModel))
|
727
747
|
self.assertEqual(
|
728
748
|
[i for i in BandModel.model_fields.keys()],
|
@@ -730,7 +750,10 @@ class TestNestedModel(TestCase):
|
|
730
750
|
)
|
731
751
|
self.assertEqual(BandModel.__qualname__, "Concert.band_1")
|
732
752
|
|
733
|
-
ManagerModel =
|
753
|
+
ManagerModel = t.cast(
|
754
|
+
t.Type[pydantic.BaseModel],
|
755
|
+
BandModel.model_fields["manager"].annotation,
|
756
|
+
)
|
734
757
|
self.assertTrue(issubclass(ManagerModel, pydantic.BaseModel))
|
735
758
|
self.assertEqual(
|
736
759
|
[i for i in ManagerModel.model_fields.keys()],
|
@@ -751,11 +774,14 @@ class TestNestedModel(TestCase):
|
|
751
774
|
|
752
775
|
MyConcertModel = create_pydantic_model(
|
753
776
|
Concert,
|
754
|
-
nested=(Concert.band_1.manager,),
|
777
|
+
nested=(Concert.band_1._.manager,),
|
755
778
|
model_name="MyConcertModel",
|
756
779
|
)
|
757
780
|
|
758
|
-
BandModel =
|
781
|
+
BandModel = t.cast(
|
782
|
+
t.Type[pydantic.BaseModel],
|
783
|
+
MyConcertModel.model_fields["band_1"].annotation,
|
784
|
+
)
|
759
785
|
self.assertEqual(BandModel.__qualname__, "MyConcertModel.band_1")
|
760
786
|
|
761
787
|
ManagerModel = BandModel.model_fields["manager"].annotation
|
@@ -763,7 +789,7 @@ class TestNestedModel(TestCase):
|
|
763
789
|
ManagerModel.__qualname__, "MyConcertModel.band_1.manager"
|
764
790
|
)
|
765
791
|
|
766
|
-
def test_cascaded_args(self):
|
792
|
+
def test_cascaded_args(self) -> None:
|
767
793
|
"""
|
768
794
|
Make sure that arguments passed to ``create_pydantic_model`` are
|
769
795
|
cascaded to nested models.
|
@@ -784,14 +810,20 @@ class TestNestedModel(TestCase):
|
|
784
810
|
table=Band, nested=True, include_default_columns=True
|
785
811
|
)
|
786
812
|
|
787
|
-
ManagerModel =
|
813
|
+
ManagerModel = t.cast(
|
814
|
+
t.Type[pydantic.BaseModel],
|
815
|
+
BandModel.model_fields["manager"].annotation,
|
816
|
+
)
|
788
817
|
self.assertTrue(issubclass(ManagerModel, pydantic.BaseModel))
|
789
818
|
self.assertEqual(
|
790
819
|
[i for i in ManagerModel.model_fields.keys()],
|
791
820
|
["id", "name", "country"],
|
792
821
|
)
|
793
822
|
|
794
|
-
CountryModel =
|
823
|
+
CountryModel = t.cast(
|
824
|
+
t.Type[pydantic.BaseModel],
|
825
|
+
ManagerModel.model_fields["country"].annotation,
|
826
|
+
)
|
795
827
|
self.assertTrue(issubclass(CountryModel, pydantic.BaseModel))
|
796
828
|
self.assertEqual(
|
797
829
|
[i for i in CountryModel.model_fields.keys()], ["id", "name"]
|
@@ -823,13 +855,22 @@ class TestRecursionDepth(TestCase):
|
|
823
855
|
table=Concert, nested=True, max_recursion_depth=2
|
824
856
|
)
|
825
857
|
|
826
|
-
VenueModel =
|
858
|
+
VenueModel = t.cast(
|
859
|
+
t.Type[pydantic.BaseModel],
|
860
|
+
ConcertModel.model_fields["venue"].annotation,
|
861
|
+
)
|
827
862
|
self.assertTrue(issubclass(VenueModel, pydantic.BaseModel))
|
828
863
|
|
829
|
-
BandModel =
|
864
|
+
BandModel = t.cast(
|
865
|
+
t.Type[pydantic.BaseModel],
|
866
|
+
ConcertModel.model_fields["band"].annotation,
|
867
|
+
)
|
830
868
|
self.assertTrue(issubclass(BandModel, pydantic.BaseModel))
|
831
869
|
|
832
|
-
ManagerModel =
|
870
|
+
ManagerModel = t.cast(
|
871
|
+
t.Type[pydantic.BaseModel],
|
872
|
+
BandModel.model_fields["manager"].annotation,
|
873
|
+
)
|
833
874
|
self.assertTrue(issubclass(ManagerModel, pydantic.BaseModel))
|
834
875
|
|
835
876
|
# We should have hit the recursion depth:
|
@@ -851,7 +892,7 @@ class TestDBColumnName(TestCase):
|
|
851
892
|
|
852
893
|
model = BandModel(regrettable_column_name="test")
|
853
894
|
|
854
|
-
self.assertEqual(model.name, "test")
|
895
|
+
self.assertEqual(model.name, "test") # type: ignore
|
855
896
|
|
856
897
|
|
857
898
|
class TestJSONSchemaExtra(TestCase):
|
@@ -885,7 +926,7 @@ class TestPydanticExtraFields(TestCase):
|
|
885
926
|
config: pydantic.config.ConfigDict = {"extra": "forbid"}
|
886
927
|
model = create_pydantic_model(Band, pydantic_config=config)
|
887
928
|
|
888
|
-
self.assertEqual(model.model_config
|
929
|
+
self.assertEqual(model.model_config.get("extra"), "forbid")
|
889
930
|
|
890
931
|
def test_pydantic_invalid_extra_fields(self) -> None:
|
891
932
|
"""
|
tests/query/test_functions.py
DELETED
@@ -1,238 +0,0 @@
|
|
1
|
-
from unittest import TestCase
|
2
|
-
|
3
|
-
from piccolo.columns import Integer, Text, Varchar
|
4
|
-
from piccolo.query.functions import Cast, Length, Reverse, Upper
|
5
|
-
from piccolo.querystring import QueryString
|
6
|
-
from piccolo.table import create_db_tables_sync, drop_db_tables_sync
|
7
|
-
from tests.base import engines_skip
|
8
|
-
from tests.example_apps.music.tables import Band, Manager
|
9
|
-
|
10
|
-
|
11
|
-
class FunctionTest(TestCase):
|
12
|
-
tables = (Band, Manager)
|
13
|
-
|
14
|
-
def setUp(self) -> None:
|
15
|
-
create_db_tables_sync(*self.tables)
|
16
|
-
|
17
|
-
manager = Manager({Manager.name: "Guido"})
|
18
|
-
manager.save().run_sync()
|
19
|
-
|
20
|
-
band = Band(
|
21
|
-
{
|
22
|
-
Band.name: "Pythonistas",
|
23
|
-
Band.manager: manager,
|
24
|
-
Band.popularity: 1000,
|
25
|
-
}
|
26
|
-
)
|
27
|
-
band.save().run_sync()
|
28
|
-
|
29
|
-
def tearDown(self) -> None:
|
30
|
-
drop_db_tables_sync(*self.tables)
|
31
|
-
|
32
|
-
|
33
|
-
class TestUpperFunction(FunctionTest):
|
34
|
-
|
35
|
-
def test_column(self):
|
36
|
-
"""
|
37
|
-
Make sure we can uppercase a column's value.
|
38
|
-
"""
|
39
|
-
response = Band.select(Upper(Band.name)).run_sync()
|
40
|
-
self.assertListEqual(response, [{"upper": "PYTHONISTAS"}])
|
41
|
-
|
42
|
-
def test_alias(self):
|
43
|
-
response = Band.select(Upper(Band.name, alias="name")).run_sync()
|
44
|
-
self.assertListEqual(response, [{"name": "PYTHONISTAS"}])
|
45
|
-
|
46
|
-
def test_joined_column(self):
|
47
|
-
"""
|
48
|
-
Make sure we can uppercase a column's value from a joined table.
|
49
|
-
"""
|
50
|
-
response = Band.select(Upper(Band.manager._.name)).run_sync()
|
51
|
-
self.assertListEqual(response, [{"upper": "GUIDO"}])
|
52
|
-
|
53
|
-
|
54
|
-
@engines_skip("sqlite")
|
55
|
-
class TestNested(FunctionTest):
|
56
|
-
"""
|
57
|
-
Skip the the test for SQLite, as it doesn't support ``Reverse``.
|
58
|
-
"""
|
59
|
-
|
60
|
-
def test_nested(self):
|
61
|
-
"""
|
62
|
-
Make sure we can nest functions.
|
63
|
-
"""
|
64
|
-
response = Band.select(Upper(Reverse(Band.name))).run_sync()
|
65
|
-
self.assertListEqual(response, [{"upper": "SATSINOHTYP"}])
|
66
|
-
|
67
|
-
def test_nested_with_joined_column(self):
|
68
|
-
"""
|
69
|
-
Make sure nested functions can be used on a column from a joined table.
|
70
|
-
"""
|
71
|
-
response = Band.select(Upper(Reverse(Band.manager._.name))).run_sync()
|
72
|
-
self.assertListEqual(response, [{"upper": "ODIUG"}])
|
73
|
-
|
74
|
-
def test_nested_within_querystring(self):
|
75
|
-
"""
|
76
|
-
If we wrap a function in a custom QueryString - make sure the columns
|
77
|
-
are still accessible, so joins are successful.
|
78
|
-
"""
|
79
|
-
response = Band.select(
|
80
|
-
QueryString("CONCAT({}, '!')", Upper(Band.manager._.name)),
|
81
|
-
).run_sync()
|
82
|
-
|
83
|
-
self.assertListEqual(response, [{"concat": "GUIDO!"}])
|
84
|
-
|
85
|
-
|
86
|
-
class TestWhereClause(FunctionTest):
|
87
|
-
|
88
|
-
def test_where(self):
|
89
|
-
"""
|
90
|
-
Make sure where clauses work with functions.
|
91
|
-
"""
|
92
|
-
response = (
|
93
|
-
Band.select(Band.name)
|
94
|
-
.where(Upper(Band.name) == "PYTHONISTAS")
|
95
|
-
.run_sync()
|
96
|
-
)
|
97
|
-
self.assertListEqual(response, [{"name": "Pythonistas"}])
|
98
|
-
|
99
|
-
def test_where_with_joined_column(self):
|
100
|
-
"""
|
101
|
-
Make sure where clauses work with functions, when a joined column is
|
102
|
-
used.
|
103
|
-
"""
|
104
|
-
response = (
|
105
|
-
Band.select(Band.name)
|
106
|
-
.where(Upper(Band.manager._.name) == "GUIDO")
|
107
|
-
.run_sync()
|
108
|
-
)
|
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
|