Skip to content

Commit f089e9d

Browse files
zoliszeredigrigi
authored andcommitted
Add documentation/examples and Upper,Lower (tortoise#225)
1 parent 477ef43 commit f089e9d

File tree

5 files changed

+51
-6
lines changed

5 files changed

+51
-6
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Enhancements:
1414
- Models, Fields & QuerySets have significant type annotation improvements,
1515
leading to better IDE integration and more comprehensive static analysis.
1616
- Fetching records from the DB is now up to 25% faster.
17-
- Database functions ``Trim()``, ``Length()``, ``Coalesce()`` added to tortoise.functions module.
17+
- Database functions ``Trim()``, ``Length()``, ``Coalesce()``, ``Lower()``, ``Upper()`` added to tortoise.functions module.
1818
- Annotations can be selected inside ``Queryset.values()`` and ``Queryset.values_list()`` expressions.
1919
- Added support for Python 3.8
2020
- The Foreign Key property is now ``await``-able as long as one didn't populate it via ``.prefetch_related()``

docs/query.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,15 +127,19 @@ In cases like this you could use ``values()`` or ``values_list()`` to produce mo
127127
# And it will be done in one query
128128
events = await Event.filter(id__in=[1,2,3]).values('id', 'name', tournament_name='tournament__name')
129129
130-
QuerySet also supports aggregation through ``.annotate()`` method
130+
QuerySet also supports aggregation and database functions through ``.annotate()`` method
131131

132132
.. code-block:: python3
133133
134-
from tortoise.aggregation import Count
134+
from tortoise.functions import Count, Trim, Lower, Upper, Coalesce
135135
136136
# This query will fetch all tournaments with 10 or more events, and will
137137
# populate filed `.events_count` on instances with corresponding value
138138
await Tournament.annotate(events_count=Count('events')).filter(events_count__gte=10)
139+
await Tournament.annotate(clean_name=Trim('name'))).filter(clean_name='tournament')
140+
await Tournament.annotate(name_upper=Upper('name'))).filter(name_upper='TOURNAMENT')
141+
await Tournament.annotate(name_lower=Lower('name'))).filter(name_lower='tournament')
142+
await Tournament.annotate(desc_clean=Coalesce('desc', ''))).filter(desc_clean='')
139143
140144
Check `examples <https://github.com/tortoise/tortoise-orm/tree/master/examples>`_ to see it all in work
141145

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from tortoise import Tortoise, fields, run_async
2-
from tortoise.aggregation import Count, Min, Sum
2+
from tortoise.functions import Coalesce, Count, Length, Lower, Min, Sum, Trim, Upper
33
from tortoise.models import Model
44

55

66
class Tournament(Model):
77
id = fields.IntField(pk=True)
88
name = fields.TextField()
9+
desc = fields.TextField(null=True)
910

1011
def __str__(self):
1112
return self.name
@@ -34,9 +35,10 @@ def __str__(self):
3435
async def run():
3536
await Tortoise.init(db_url="sqlite://:memory:", modules={"models": ["__main__"]})
3637
await Tortoise.generate_schemas()
37-
tournament = await Tournament.create(name="New Tournament")
38+
tournament = await Tournament.create(name="New Tournament", desc="great")
3839
await tournament.save()
3940
await Tournament.create(name="Second tournament")
41+
await Tournament.create(name=" final tournament ")
4042
await Event(name="Without participants", tournament_id=tournament.id).save()
4143
event = Event(name="Test", tournament_id=tournament.id)
4244
await event.save()
@@ -56,6 +58,21 @@ async def run():
5658

5759
print(await Event.all().annotate(tournament_test_id=Sum("tournament__id")).first())
5860

61+
print(await Tournament.annotate(clean_desciption=Coalesce("desc")).filter(clean_desciption=""))
62+
63+
print(
64+
await Tournament.annotate(trimmed_name=Trim("name")).filter(trimmed_name="final tournament")
65+
)
66+
67+
print(
68+
await Tournament.annotate(name_len=Length("name")).filter(
69+
name_len__gt=len("New Tournament")
70+
)
71+
)
72+
73+
print(await Tournament.annotate(name_lo=Lower("name")).filter(name_lo="new tournament"))
74+
print(await Tournament.annotate(name_lo=Upper("name")).filter(name_lo="NEW TOURNAMENT"))
75+
5976

6077
if __name__ == "__main__":
6178
run_async(run())

tests/test_filtering.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from tests.testmodels import Event, IntFields, Reporter, Team, Tournament
22
from tortoise.contrib import test
3-
from tortoise.functions import Coalesce, Count, Length, Trim
3+
from tortoise.functions import Coalesce, Count, Length, Lower, Trim, Upper
44
from tortoise.query_utils import Q
55

66

@@ -330,6 +330,20 @@ async def test_filter_by_aggregation_field_comparison_length(self):
330330
self.assertEqual(len(tournaments), 1)
331331
self.assertSetEqual({t.name for t in tournaments}, {"Tournament"})
332332

333+
async def test_filter_by_annotation_lower(self):
334+
await Tournament.create(name="Tournament")
335+
await Tournament.create(name="NEW Tournament")
336+
tournaments = await Tournament.annotate(name_lower=Lower("name"))
337+
self.assertEqual(len(tournaments), 2)
338+
self.assertSetEqual({t.name_lower for t in tournaments}, {"tournament", "new tournament"})
339+
340+
async def test_filter_by_annotation_upper(self):
341+
await Tournament.create(name="ToUrnAmEnT")
342+
await Tournament.create(name="new TOURnament")
343+
tournaments = await Tournament.annotate(name_upper=Upper("name"))
344+
self.assertEqual(len(tournaments), 2)
345+
self.assertSetEqual({t.name_upper for t in tournaments}, {"TOURNAMENT", "NEW TOURNAMENT"})
346+
333347
async def test_values_select_relation(self):
334348
with self.assertRaises(ValueError):
335349
tournament = await Tournament.create(name="New Tournament")

tortoise/functions.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
from pypika.functions import Coalesce as PypikaCoalesce
44
from pypika.functions import Count as PypikaCount
55
from pypika.functions import Length as PypikaLength
6+
from pypika.functions import Lower as PypikaLower
67
from pypika.functions import Max as PypikaMax
78
from pypika.functions import Min as PypikaMin
89
from pypika.functions import Sum as PypikaSum
910
from pypika.functions import Trim as PypikaTrim
11+
from pypika.functions import Upper as PypikaUpper
1012
from pypika.terms import AggregateFunction
1113
from pypika.terms import Function as BaseFunction
1214

@@ -80,6 +82,14 @@ class Coalesce(Function):
8082
database_func = PypikaCoalesce
8183

8284

85+
class Lower(Function):
86+
database_func = PypikaLower
87+
88+
89+
class Upper(Function):
90+
database_func = PypikaUpper
91+
92+
8393
##############################################################################
8494
# Aggregate functions
8595
##############################################################################

0 commit comments

Comments
 (0)