@@ -38,7 +38,8 @@ from pydantic_redis import RedisConfig, Model, Store
38
38
39
39
class Author (Model ):
40
40
"""
41
- An Author model, just like a pydantic model with appropriate type annotations
41
+ An Author model, just like a pydantic model with appropriate
42
+ type annotations
42
43
NOTE : The `_primary_key_field` is mandatory
43
44
"""
44
45
_primary_key_field: str = ' name'
@@ -51,18 +52,24 @@ class Book(Model):
51
52
A Book model.
52
53
53
54
Models can have the following field types
54
- - The usual i.e. float, int, dict, list, date, str, dict, Optional etc as long as they are serializable by orjson
55
+ - The usual i.e. float, int, dict, list, date, str, dict, Optional etc
56
+ as long as they are serializable by orjson
55
57
- Nested models e.g. `author: Author` or `author: Optional[Author]`
56
- - List of nested models e.g. `authors: List[Author]` or `authors: Optional[List[Author]]`
57
- - Tuples including nested models e.g. `access_log: Tuple[Author, date]` or `access_log: Optional[Tuple[Author, date]]]`
58
+ - List of nested models e.g. `authors: List[Author]`
59
+ or `authors: Optional[List[Author]]`
60
+ - Tuples including nested models e.g. `access_log: Tuple[Author, date]`
61
+ or `access_log: Optional[Tuple[Author, date]]]`
58
62
59
- NOTE : 1. Any nested model whether plain or in a list or tuple will automatically inserted into the redis store
60
- when the parent model is inserted. e.g. a Book with an author field, when inserted, will also insert
61
- the author. The author can then be queried directly if that's something one wishes to do.
63
+ NOTE : 1. Any nested model whether plain or in a list or tuple will automatically
64
+ inserted into the redis store when the parent model is inserted.
65
+ e.g. a Book with an author field, when inserted, will also insert
66
+ the author. The author can then be queried directly if that's something
67
+ one wishes to do.
62
68
63
- 2. When a parent model is inserted with a nested model instance that already exists, the older nested model
64
- instance is overwritten. This is one way of updating nested models. All parent models that contain that nested
65
- model instance will see the change.
69
+ 2. When a parent model is inserted with a nested model instance that
70
+ already exists, the older nested model instance is overwritten.
71
+ This is one way of updating nested models.
72
+ All parent models that contain that nested model instance will see the change.
66
73
"""
67
74
_primary_key_field: str = ' title'
68
75
title: str
@@ -81,8 +88,10 @@ class Library(Model):
81
88
82
89
About Nested Model Performance
83
90
---
84
- To minimize the performance penalty for nesting models, we use REDIS EVALSHA to eagerly load the nested models
85
- before the response is returned to the client. This ensures that only ONE network call is made every time.
91
+ To minimize the performance penalty for nesting models,
92
+ we use REDIS EVALSHA to eagerly load the nested models
93
+ before the response is returned to the client.
94
+ This ensures that only ONE network call is made every time.
86
95
"""
87
96
_primary_key_field: str = ' name'
88
97
name: str
@@ -180,15 +189,26 @@ print(all_books)
180
189
# Prints [Book(title="Oliver Twist", author="Charles Dickens", published_on=date(year=1215, month=4, day=4),
181
190
# in_stock=False), Book(...]
182
191
192
+ # or paginate i.e. skip some books and return only upto a given number
193
+ paginated_books = Book.select(skip = 2 , limit = 2 )
194
+ print (paginated_books)
195
+
183
196
# Get some, with all fields shown. Data returned is a list of models instances.
184
197
some_books = Book.select(ids = [" Oliver Twist" , " Jane Eyre" ])
185
198
print (some_books)
186
199
200
+ # Note: Pagination does not work when ids are provided i.e.
201
+ assert some_books == Book.select(ids = [" Oliver Twist" , " Jane Eyre" ], skip = 100 , limit = 10 )
202
+
187
203
# Get all, with only a few fields shown. Data returned is a list of dictionaries.
188
204
books_with_few_fields = Book.select(columns = [" author" , " in_stock" ])
189
205
print (books_with_few_fields)
190
206
# Prints [{"author": "'Charles Dickens", "in_stock": "True"},...]
191
207
208
+ # or paginate i.e. skip some books and return only upto a given number
209
+ paginated_books_with_few_fields = Book.select(columns = [" author" , " in_stock" ], skip = 2 , limit = 2 )
210
+ print (paginated_books_with_few_fields)
211
+
192
212
# Get some, with only some fields shown. Data returned is a list of dictionaries.
193
213
some_books_with_few_fields = Book.select(ids = [" Oliver Twist" , " Jane Eyre" ], columns = [" author" , " in_stock" ])
194
214
print (some_books_with_few_fields)
@@ -217,13 +237,15 @@ from datetime import date
217
237
from typing import Tuple, List, Optional
218
238
from pydantic_redis.asyncio import RedisConfig, Model, Store
219
239
220
- # The features are exactly the same as the synchronous version, except for the ability
221
- # to return coroutines when `insert`, `update`, `select` or `delete` are called.
240
+ # The features are exactly the same as the synchronous version,
241
+ # except for the ability to return coroutines when `insert`,
242
+ # `update`, `select` or `delete` are called.
222
243
223
244
224
245
class Author (Model ):
225
246
"""
226
- An Author model, just like a pydantic model with appropriate type annotations
247
+ An Author model, just like a pydantic model with appropriate
248
+ type annotations
227
249
NOTE : The `_primary_key_field` is mandatory
228
250
"""
229
251
_primary_key_field: str = ' name'
@@ -236,18 +258,24 @@ class Book(Model):
236
258
A Book model.
237
259
238
260
Models can have the following field types
239
- - The usual i.e. float, int, dict, list, date, str, dict, Optional etc as long as they are serializable by orjson
261
+ - The usual i.e. float, int, dict, list, date, str, dict, Optional etc
262
+ as long as they are serializable by orjson
240
263
- Nested models e.g. `author: Author` or `author: Optional[Author]`
241
- - List of nested models e.g. `authors: List[Author]` or `authors: Optional[List[Author]]`
242
- - Tuples including nested models e.g. `access_log: Tuple[Author, date]` or `access_log: Optional[Tuple[Author, date]]]`
264
+ - List of nested models e.g. `authors: List[Author]`
265
+ or `authors: Optional[List[Author]]`
266
+ - Tuples including nested models e.g. `access_log: Tuple[Author, date]`
267
+ or `access_log: Optional[Tuple[Author, date]]]`
243
268
244
- NOTE : 1. Any nested model whether plain or in a list or tuple will automatically inserted into the redis store
245
- when the parent model is inserted. e.g. a Book with an author field, when inserted, will also insert
246
- the author. The author can then be queried directly if that's something one wishes to do.
269
+ NOTE : 1. Any nested model whether plain or in a list or tuple will automatically
270
+ inserted into the redis store when the parent model is inserted.
271
+ e.g. a Book with an author field, when inserted, will also insert
272
+ the author. The author can then be queried directly if that's something
273
+ one wishes to do.
247
274
248
- 2. When a parent model is inserted with a nested model instance that already exists, the older nested model
249
- instance is overwritten. This is one way of updating nested models. All parent models that contain that nested
250
- model instance will see the change.
275
+ 2. When a parent model is inserted with a nested model instance that
276
+ already exists, the older nested model instance is overwritten.
277
+ This is one way of updating nested models.
278
+ All parent models that contain that nested model instance will see the change.
251
279
"""
252
280
_primary_key_field: str = ' title'
253
281
title: str
@@ -266,8 +294,10 @@ class Library(Model):
266
294
267
295
About Nested Model Performance
268
296
---
269
- To minimize the performance penalty for nesting models, we use REDIS EVALSHA to eagerly load the nested models
270
- before the response is returned to the client. This ensures that only ONE network call is made every time.
297
+ To minimize the performance penalty for nesting models,
298
+ we use REDIS EVALSHA to eagerly load the nested models
299
+ before the response is returned to the client.
300
+ This ensures that only ONE network call is made every time.
271
301
"""
272
302
_primary_key_field: str = ' name'
273
303
name: str
@@ -367,15 +397,26 @@ async def run_async():
367
397
# Prints [Book(title="Oliver Twist", author="Charles Dickens", published_on=date(year=1215, month=4, day=4),
368
398
# in_stock=False), Book(...]
369
399
400
+ # or paginate i.e. skip some books and return only upto a given number
401
+ paginated_books = await Book.select(skip = 2 , limit = 2 )
402
+ print (paginated_books)
403
+
370
404
# Get some, with all fields shown. Data returned is a list of models instances.
371
405
some_books = await Book.select(ids = [" Oliver Twist" , " Jane Eyre" ])
372
406
print (some_books)
373
407
408
+ # Note: Pagination does not work when ids are provided i.e.
409
+ assert some_books == await Book.select(ids = [" Oliver Twist" , " Jane Eyre" ], skip = 100 , limit = 10 )
410
+
374
411
# Get all, with only a few fields shown. Data returned is a list of dictionaries.
375
412
books_with_few_fields = await Book.select(columns = [" author" , " in_stock" ])
376
413
print (books_with_few_fields)
377
414
# Prints [{"author": "'Charles Dickens", "in_stock": "True"},...]
378
415
416
+ # or paginate i.e. skip some books and return only upto a given number
417
+ paginated_books_with_few_fields = await Book.select(columns = [" author" , " in_stock" ], skip = 2 , limit = 2 )
418
+ print (paginated_books_with_few_fields)
419
+
379
420
# Get some, with only some fields shown. Data returned is a list of dictionaries.
380
421
some_books_with_few_fields = await Book.select(ids = [" Oliver Twist" , " Jane Eyre" ], columns = [" author" , " in_stock" ])
381
422
print (some_books_with_few_fields)
@@ -440,30 +481,32 @@ asyncio.run(run_async())
440
481
On an average PC ~ 16GB RAM, i7 Core
441
482
442
483
```
443
- ------------------------------------------------- benchmark: 20 tests -------------------------------------------------
444
- Name (time in us) Mean Min Max
445
- -----------------------------------------------------------------------------------------------------------------------
446
- benchmark_select_columns_for_one_id[redis_store-book1] 143.5316 (1.08) 117.4340 (1.0) 347.5900 (1.0)
447
- benchmark_select_columns_for_one_id[redis_store-book3] 151.6032 (1.14) 117.6690 (1.00) 405.4620 (1.17)
448
- benchmark_select_columns_for_one_id[redis_store-book0] 133.0856 (1.0) 117.8720 (1.00) 403.9400 (1.16)
449
- benchmark_select_columns_for_one_id[redis_store-book2] 156.8152 (1.18) 118.7220 (1.01) 569.9800 (1.64)
450
- benchmark_select_columns_for_some_items[redis_store] 138.0488 (1.04) 120.1550 (1.02) 350.7040 (1.01)
451
- benchmark_delete[redis_store-Wuthering Heights] 199.9205 (1.50) 127.6990 (1.09) 1,092.2190 (3.14)
452
- benchmark_bulk_delete[redis_store] 178.4756 (1.34) 143.7480 (1.22) 647.6660 (1.86)
453
- benchmark_select_all_for_one_id[redis_store-book1] 245.7787 (1.85) 195.2030 (1.66) 528.9250 (1.52)
454
- benchmark_select_all_for_one_id[redis_store-book0] 239.1152 (1.80) 199.4360 (1.70) 767.2540 (2.21)
455
- benchmark_select_all_for_one_id[redis_store-book3] 243.8724 (1.83) 200.8060 (1.71) 535.3640 (1.54)
456
- benchmark_select_all_for_one_id[redis_store-book2] 256.1625 (1.92) 202.4630 (1.72) 701.3000 (2.02)
457
- benchmark_update[redis_store-Wuthering Heights-data0] 329.1363 (2.47) 266.9700 (2.27) 742.1360 (2.14)
458
- benchmark_select_some_items[redis_store] 301.0471 (2.26) 268.9410 (2.29) 551.1060 (1.59)
459
- benchmark_select_columns[redis_store] 313.4356 (2.36) 281.4460 (2.40) 578.7730 (1.67)
460
- benchmark_single_insert[redis_store-book2] 348.5624 (2.62) 297.3610 (2.53) 580.8780 (1.67)
461
- benchmark_single_insert[redis_store-book1] 342.1879 (2.57) 297.5410 (2.53) 650.5420 (1.87)
462
- benchmark_single_insert[redis_store-book0] 366.4513 (2.75) 310.1640 (2.64) 660.5380 (1.90)
463
- benchmark_single_insert[redis_store-book3] 377.6208 (2.84) 327.5290 (2.79) 643.4090 (1.85)
464
- benchmark_select_default[redis_store] 486.6931 (3.66) 428.8810 (3.65) 1,181.9620 (3.40)
465
- benchmark_bulk_insert[redis_store] 897.7862 (6.75) 848.7410 (7.23) 1,188.5160 (3.42)
466
- -----------------------------------------------------------------------------------------------------------------------
484
+ -------------------------------------------------- benchmark: 22 tests --------------------------------------------------
485
+ Name (time in us) Mean Min Max
486
+ -------------------------------------------------------------------------------------------------------------------------
487
+ benchmark_select_columns_for_one_id[redis_store-book2] 124.2687 (1.00) 115.4530 (1.0) 331.8030 (1.26)
488
+ benchmark_select_columns_for_one_id[redis_store-book0] 123.7213 (1.0) 115.6680 (1.00) 305.7170 (1.16)
489
+ benchmark_select_columns_for_one_id[redis_store-book3] 124.4495 (1.01) 115.9580 (1.00) 263.4370 (1.0)
490
+ benchmark_select_columns_for_one_id[redis_store-book1] 124.8431 (1.01) 117.4770 (1.02) 310.3140 (1.18)
491
+ benchmark_select_columns_for_some_items[redis_store] 128.0657 (1.04) 118.6380 (1.03) 330.2680 (1.25)
492
+ benchmark_delete[redis_store-Wuthering Heights] 131.8713 (1.07) 125.9920 (1.09) 328.9660 (1.25)
493
+ benchmark_bulk_delete[redis_store] 148.6963 (1.20) 142.3190 (1.23) 347.4750 (1.32)
494
+ benchmark_select_all_for_one_id[redis_store-book3] 211.6941 (1.71) 195.6520 (1.69) 422.8840 (1.61)
495
+ benchmark_select_all_for_one_id[redis_store-book2] 212.3612 (1.72) 195.9020 (1.70) 447.4910 (1.70)
496
+ benchmark_select_all_for_one_id[redis_store-book1] 212.9524 (1.72) 197.7530 (1.71) 423.3030 (1.61)
497
+ benchmark_select_all_for_one_id[redis_store-book0] 214.9924 (1.74) 198.8280 (1.72) 402.6310 (1.53)
498
+ benchmark_select_columns_paginated[redis_store] 227.9248 (1.84) 211.0610 (1.83) 425.8390 (1.62)
499
+ benchmark_select_some_items[redis_store] 297.5700 (2.41) 271.1510 (2.35) 572.1220 (2.17)
500
+ benchmark_select_default_paginated[redis_store] 301.7495 (2.44) 282.6500 (2.45) 490.3450 (1.86)
501
+ benchmark_select_columns[redis_store] 316.2119 (2.56) 290.6110 (2.52) 578.0310 (2.19)
502
+ benchmark_update[redis_store-Wuthering Heights-data0] 346.5816 (2.80) 304.5420 (2.64) 618.0250 (2.35)
503
+ benchmark_single_insert[redis_store-book2] 378.0613 (3.06) 337.8070 (2.93) 616.4930 (2.34)
504
+ benchmark_single_insert[redis_store-book0] 396.6513 (3.21) 347.1000 (3.01) 696.1350 (2.64)
505
+ benchmark_single_insert[redis_store-book3] 395.9082 (3.20) 361.0980 (3.13) 623.8630 (2.37)
506
+ benchmark_single_insert[redis_store-book1] 401.1377 (3.24) 363.5890 (3.15) 610.4400 (2.32)
507
+ benchmark_select_default[redis_store] 498.4673 (4.03) 428.1350 (3.71) 769.7640 (2.92)
508
+ benchmark_bulk_insert[redis_store] 1,025.0436 (8.29) 962.2230 (8.33) 1,200.3840 (4.56)
509
+ -------------------------------------------------------------------------------------------------------------------------
467
510
```
468
511
469
512
## Contributions
0 commit comments