or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

database.mdexceptions.mdfunctions.mdindex.mdintegration.mdmodels.mdquerying.mdsignals.mdtransactions.mdvalidators.md

functions.mddocs/

0

# Database Functions and Expressions

1

2

Database function support including text functions, aggregate functions, and custom expressions for advanced queries. These functions provide database-level operations that can be used in queries, annotations, and aggregations.

3

4

## Capabilities

5

6

### Function Base Classes

7

8

Base classes for creating and using database functions in queries.

9

10

```python { .api }

11

class Expression:

12

"""Base class for query expressions."""

13

14

def __init__(self, *args, **kwargs):

15

"""

16

Initialize expression.

17

18

Args:

19

*args: Expression arguments

20

**kwargs: Expression options

21

"""

22

23

class Function(Expression):

24

"""Base class for database functions."""

25

26

def __init__(self, *args, **kwargs):

27

"""

28

Initialize function with arguments.

29

30

Args:

31

*args: Function arguments (field names, values)

32

**kwargs: Function options

33

"""

34

35

class Aggregate(Function):

36

"""Base class for aggregate functions."""

37

38

def __init__(self, field, distinct=False, **kwargs):

39

"""

40

Initialize aggregate function.

41

42

Args:

43

field (str): Field name to aggregate

44

distinct (bool): Use DISTINCT in aggregation

45

**kwargs: Additional options

46

"""

47

```

48

49

### Text Functions

50

51

Functions for manipulating text and string data.

52

53

```python { .api }

54

class Trim:

55

"""Trim whitespace from edges of text."""

56

def __init__(self, field): ...

57

58

class Length:

59

"""Get length of text or binary data."""

60

def __init__(self, field): ...

61

62

class Lower:

63

"""Convert text to lowercase."""

64

def __init__(self, field): ...

65

66

class Upper:

67

"""Convert text to uppercase."""

68

def __init__(self, field): ...

69

70

class Coalesce:

71

"""Return first non-null value from arguments."""

72

def __init__(self, *fields): ...

73

74

class Concat:

75

"""Concatenate multiple text values."""

76

def __init__(self, *fields, separator=""): ...

77

78

class Substring:

79

"""Extract substring from text."""

80

def __init__(self, field, start, length=None): ...

81

82

class Replace:

83

"""Replace occurrences of substring."""

84

def __init__(self, field, search, replace): ...

85

```

86

87

### Mathematical Functions

88

89

Functions for mathematical operations and calculations.

90

91

```python { .api }

92

class Abs:

93

"""Absolute value of number."""

94

def __init__(self, field): ...

95

96

class Ceil:

97

"""Ceiling (round up) of number."""

98

def __init__(self, field): ...

99

100

class Floor:

101

"""Floor (round down) of number."""

102

def __init__(self, field): ...

103

104

class Round:

105

"""Round number to specified decimal places."""

106

def __init__(self, field, precision=0): ...

107

108

class Mod:

109

"""Modulo operation."""

110

def __init__(self, field, divisor): ...

111

112

class Power:

113

"""Raise number to power."""

114

def __init__(self, field, exponent): ...

115

116

class Sqrt:

117

"""Square root of number."""

118

def __init__(self, field): ...

119

```

120

121

### Date and Time Functions

122

123

Functions for working with date and time values.

124

125

```python { .api }

126

class Now:

127

"""Current date and time."""

128

def __init__(self): ...

129

130

class Extract:

131

"""Extract part of date/time value."""

132

def __init__(self, field, lookup_type):

133

"""

134

Args:

135

field (str): Date/time field name

136

lookup_type (str): Part to extract ('year', 'month', 'day', 'hour', etc.)

137

"""

138

139

class DateDiff:

140

"""Difference between two dates."""

141

def __init__(self, field1, field2, interval='day'): ...

142

143

class DateAdd:

144

"""Add interval to date."""

145

def __init__(self, field, interval, amount): ...

146

147

class DateFormat:

148

"""Format date as string."""

149

def __init__(self, field, format_string): ...

150

```

151

152

### Aggregate Functions

153

154

Functions that compute single values from multiple rows.

155

156

```python { .api }

157

class Count:

158

"""Count number of rows or non-null values."""

159

def __init__(self, field="*", distinct=False): ...

160

161

class Sum:

162

"""Sum of numeric values."""

163

def __init__(self, field, distinct=False): ...

164

165

class Avg:

166

"""Average of numeric values."""

167

def __init__(self, field, distinct=False): ...

168

169

class Max:

170

"""Maximum value."""

171

def __init__(self, field): ...

172

173

class Min:

174

"""Minimum value."""

175

def __init__(self, field): ...

176

177

class StdDev:

178

"""Standard deviation."""

179

def __init__(self, field): ...

180

181

class Variance:

182

"""Variance."""

183

def __init__(self, field): ...

184

```

185

186

### Conditional Functions

187

188

Functions for conditional logic in queries.

189

190

```python { .api }

191

class Case:

192

"""Conditional CASE expression."""

193

def __init__(self, *cases, default=None):

194

"""

195

Args:

196

*cases: Tuple pairs of (condition, result)

197

default: Default value if no conditions match

198

"""

199

200

class When:

201

"""Condition for CASE expression."""

202

def __init__(self, condition, then): ...

203

204

class Greatest:

205

"""Return greatest value from multiple fields."""

206

def __init__(self, *fields): ...

207

208

class Least:

209

"""Return smallest value from multiple fields."""

210

def __init__(self, *fields): ...

211

```

212

213

## Usage Examples

214

215

### Text Function Examples

216

217

```python

218

from tortoise.functions import Trim, Length, Lower, Upper, Coalesce, Concat

219

220

class User(Model):

221

id = fields.IntField(pk=True)

222

first_name = fields.CharField(max_length=50)

223

last_name = fields.CharField(max_length=50)

224

email = fields.CharField(max_length=100)

225

bio = fields.TextField(null=True)

226

227

# Text manipulation

228

users_with_clean_names = await User.annotate(

229

clean_first_name=Trim('first_name'),

230

name_length=Length('first_name'),

231

lower_email=Lower('email'),

232

upper_name=Upper('first_name')

233

).all()

234

235

# Concatenation

236

users_with_full_name = await User.annotate(

237

full_name=Concat('first_name', 'last_name', separator=' ')

238

).all()

239

240

# Handle null values

241

users_with_bio = await User.annotate(

242

display_bio=Coalesce('bio', 'No bio available')

243

).all()

244

```

245

246

### Mathematical Function Examples

247

248

```python

249

from tortoise.functions import Abs, Round, Mod

250

251

class Product(Model):

252

id = fields.IntField(pk=True)

253

name = fields.CharField(max_length=100)

254

price = fields.DecimalField(max_digits=10, decimal_places=2)

255

discount = fields.DecimalField(max_digits=5, decimal_places=2, default=0)

256

257

# Mathematical operations

258

products_with_calculations = await Product.annotate(

259

abs_discount=Abs('discount'),

260

rounded_price=Round('price', 2),

261

price_mod=Mod('price', 10)

262

).all()

263

```

264

265

### Date Function Examples

266

267

```python

268

from tortoise.functions import Extract, Now

269

270

class Order(Model):

271

id = fields.IntField(pk=True)

272

created_at = fields.DatetimeField(auto_now_add=True)

273

total = fields.DecimalField(max_digits=10, decimal_places=2)

274

275

# Date operations

276

orders_by_year = await Order.annotate(

277

year=Extract('created_at', 'year'),

278

month=Extract('created_at', 'month'),

279

day=Extract('created_at', 'day')

280

).all()

281

282

# Current time

283

current_time = await Order.annotate(

284

current_time=Now()

285

).first()

286

```

287

288

### Aggregate Function Examples

289

290

```python

291

from tortoise.functions import Count, Sum, Avg, Max, Min

292

293

class Post(Model):

294

id = fields.IntField(pk=True)

295

title = fields.CharField(max_length=200)

296

author = fields.ForeignKeyField('models.User', related_name='posts')

297

view_count = fields.IntField(default=0)

298

created_at = fields.DatetimeField(auto_now_add=True)

299

300

# Simple aggregation

301

stats = await Post.aggregate(

302

total_posts=Count('id'),

303

total_views=Sum('view_count'),

304

avg_views=Avg('view_count'),

305

max_views=Max('view_count'),

306

min_views=Min('view_count')

307

)

308

309

# Aggregate with grouping

310

author_stats = await User.annotate(

311

post_count=Count('posts'),

312

total_views=Sum('posts__view_count'),

313

avg_views=Avg('posts__view_count')

314

).filter(post_count__gt=0).all()

315

316

# Distinct aggregation

317

unique_authors = await Post.aggregate(

318

author_count=Count('author', distinct=True)

319

)

320

```

321

322

### Conditional Function Examples

323

324

```python

325

from tortoise.functions import Case, When

326

from tortoise.queryset import Q

327

328

class User(Model):

329

id = fields.IntField(pk=True)

330

age = fields.IntField()

331

is_premium = fields.BooleanField(default=False)

332

posts_count = fields.IntField(default=0)

333

334

# Conditional logic

335

users_with_category = await User.annotate(

336

age_category=Case(

337

When(Q(age__lt=18), then='Minor'),

338

When(Q(age__lt=65), then='Adult'),

339

default='Senior'

340

),

341

user_type=Case(

342

When(Q(is_premium=True), then='Premium'),

343

When(Q(posts_count__gt=10), then='Active'),

344

default='Regular'

345

)

346

).all()

347

348

# Complex conditions

349

users_with_status = await User.annotate(

350

status=Case(

351

When(Q(is_premium=True) & Q(posts_count__gt=50), then='VIP'),

352

When(Q(is_premium=True), then='Premium'),

353

When(Q(posts_count__gt=20), then='Active'),

354

When(Q(posts_count__gt=5), then='Regular'),

355

default='New'

356

)

357

).all()

358

```

359

360

### Window Functions

361

362

Advanced analytical functions for complex calculations.

363

364

```python

365

from tortoise.functions import RowNumber, Rank, DenseRank

366

367

class Sale(Model):

368

id = fields.IntField(pk=True)

369

product_name = fields.CharField(max_length=100)

370

amount = fields.DecimalField(max_digits=10, decimal_places=2)

371

sale_date = fields.DateField()

372

region = fields.CharField(max_length=50)

373

374

# Window functions (if supported by database)

375

sales_with_ranking = await Sale.annotate(

376

row_number=RowNumber().over(order_by=['amount']),

377

rank_by_amount=Rank().over(order_by=['-amount']),

378

dense_rank=DenseRank().over(

379

partition_by=['region'],

380

order_by=['-amount']

381

)

382

).all()

383

```

384

385

### Custom Functions

386

387

Creating custom database functions for specific needs.

388

389

```python

390

from tortoise.expressions import Function

391

392

class CustomFunction(Function):

393

"""Custom database function."""

394

database_func = 'CUSTOM_FUNC' # SQL function name

395

396

def __init__(self, field, param1, param2=None):

397

super().__init__(field, param1, param2)

398

399

# Usage

400

results = await MyModel.annotate(

401

custom_result=CustomFunction('my_field', 'param_value')

402

).all()

403

```

404

405

### Function Composition

406

407

Combining multiple functions for complex operations.

408

409

```python

410

from tortoise.functions import Lower, Trim, Length, Concat

411

412

# Compose multiple functions

413

users_processed = await User.annotate(

414

# Chain text operations

415

clean_email=Lower(Trim('email')),

416

417

# Use function results in other functions

418

full_name_length=Length(

419

Concat('first_name', 'last_name', separator=' ')

420

),

421

422

# Nested function calls

423

formatted_name=Upper(

424

Trim(

425

Concat('first_name', 'last_name', separator=' ')

426

)

427

)

428

).all()

429

```

430

431

### Database-Specific Functions

432

433

Using database-specific functions through contrib modules.

434

435

```python

436

# PostgreSQL-specific functions

437

from tortoise.contrib.postgres.functions import ArrayAgg, JsonAgg

438

439

# MySQL-specific functions

440

from tortoise.contrib.mysql.functions import GroupConcat

441

442

# SQLite-specific functions

443

from tortoise.contrib.sqlite.functions import Julianday

444

445

# PostgreSQL array aggregation

446

tags_by_post = await Post.annotate(

447

tag_names=ArrayAgg('tags__name')

448

).prefetch_related('tags').all()

449

450

# MySQL group concatenation

451

user_emails = await User.aggregate(

452

all_emails=GroupConcat('email', separator=';')

453

)

454

```