Skip to content
This repository was archived by the owner on Aug 19, 2025. It is now read-only.

Commit 0df624e

Browse files
Add support for bulk_create (#146)
Co-authored-by: Amin Alaee <[email protected]>
1 parent ea14b68 commit 0df624e

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed

docs/making_queries.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,20 @@ await Note.objects.create(text="Call Mum.", completed=True)
141141
await Note.objects.create(text="Send invoices.", completed=True)
142142
```
143143

144+
### .bulk_create()
145+
146+
You need to pass a list of dictionaries of required fields to create multiple objects:
147+
148+
```python
149+
await Product.objects.bulk_create(
150+
[
151+
{"data": {"foo": 123}, "value": 123.456, "status": StatusEnum.RELEASED},
152+
{"data": {"foo": 456}, "value": 456.789, "status": StatusEnum.DRAFT},
153+
154+
]
155+
)
156+
```
157+
144158
### .delete()
145159

146160
You can `delete` instances by calling `.delete()` on a queryset:

orm/models.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323

2424
def _update_auto_now_fields(values, fields):
2525
for key, value in fields.items():
26-
if isinstance(value, DateTime) and value.auto_now:
27-
values[key] = value.validator.get_default_value()
28-
elif isinstance(value, Date) and value.auto_now:
26+
if isinstance(value, (DateTime, Date)) and value.auto_now:
2927
values[key] = value.validator.get_default_value()
3028
return values
3129

@@ -403,7 +401,7 @@ async def first(self, **kwargs):
403401
if rows:
404402
return rows[0]
405403

406-
async def create(self, **kwargs):
404+
def _validate_kwargs(self, **kwargs):
407405
fields = self.model_cls.fields
408406
validator = typesystem.Schema(
409407
fields={key: value.validator for key, value in fields.items()}
@@ -412,7 +410,10 @@ async def create(self, **kwargs):
412410
for key, value in fields.items():
413411
if value.validator.read_only and value.validator.has_default():
414412
kwargs[key] = value.validator.get_default_value()
413+
return kwargs
415414

415+
async def create(self, **kwargs):
416+
kwargs = self._validate_kwargs(**kwargs)
416417
instance = self.model_cls(**kwargs)
417418
expr = self.table.insert().values(**kwargs)
418419

@@ -423,6 +424,12 @@ async def create(self, **kwargs):
423424

424425
return instance
425426

427+
async def bulk_create(self, objs: typing.List[typing.Dict]) -> None:
428+
new_objs = [self._validate_kwargs(**obj) for obj in objs]
429+
430+
expr = self.table.insert().values(new_objs)
431+
await self.database.execute(expr)
432+
426433
async def delete(self) -> None:
427434
expr = self.table.delete()
428435
for filter_clause in self.filter_clauses:

tests/test_columns.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,20 @@ class Product(orm.Model):
142142
}
143143

144144
await Product.objects.create()
145+
146+
147+
async def test_bulk_create():
148+
await Product.objects.bulk_create(
149+
[
150+
{"data": {"foo": 123}, "value": 123.456, "status": StatusEnum.RELEASED},
151+
{"data": {"foo": 456}, "value": 456.789, "status": StatusEnum.DRAFT},
152+
]
153+
)
154+
products = await Product.objects.all()
155+
assert len(products) == 2
156+
assert products[0].data == {"foo": 123}
157+
assert products[0].value == 123.456
158+
assert products[0].status == StatusEnum.RELEASED
159+
assert products[1].data == {"foo": 456}
160+
assert products[1].value == 456.789
161+
assert products[1].status == StatusEnum.DRAFT

0 commit comments

Comments
 (0)