Skip to content

Commit 1b186bd

Browse files
committed
Support empty new models. #11
1 parent 66f174c commit 1b186bd

File tree

4 files changed

+28
-1
lines changed

4 files changed

+28
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
### Added
66

7+
- Added support for manually specifying model to act on if new_models is empty. #11.
78
- Added exclude_fields argument. Issue #15, pull request #16 from [@VKFisher](https://github.com/VKFisher).
89

910
## [3.0.1] - 2020-08-05

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ Combine bulk create, update, and delete. Make the DB match a set of in-memory ob
7979
- `skip_creates`: (optional) If truthy, will not perform any object creations needed to fully sync. Defaults to not skip.
8080
- `skip_updates`: (optional) If truthy, will not perform any object updates needed to fully sync. Defaults to not skip.
8181
- `skip_deletes`: (optional) If truthy, will not perform any object deletions needed to fully sync. Defaults to not skip.
82+
- `db_class`: (optional) Model class to operate on. If new_models always contains at least one object, this can be set automatically so is optional.
8283

8384
- Returns a dict:
8485
```

bulk_sync/__init__.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def bulk_sync(
1717
skip_creates=False,
1818
skip_updates=False,
1919
skip_deletes=False,
20+
db_class=None,
2021
):
2122
""" Combine bulk create, update, and delete. Make the DB match a set of in-memory objects.
2223
@@ -34,8 +35,23 @@ def bulk_sync(
3435
`skip_creates`: If truthy, will not perform any object creations needed to fully sync. Defaults to not skip.
3536
`skip_updates`: If truthy, will not perform any object updates needed to fully sync. Defaults to not skip.
3637
`skip_deletes`: If truthy, will not perform any object deletions needed to fully sync. Defaults to not skip.
38+
`db_class`: (optional) Model class to operate on. If new_models always contains at least one object, this can
39+
be set automatically so is optional.
3740
"""
38-
db_class = new_models[0].__class__
41+
42+
if db_class is None:
43+
try:
44+
db_class = new_models[0].__class__
45+
except IndexError:
46+
try:
47+
db_class = new_models.model
48+
except AttributeError:
49+
db_class = None
50+
51+
if db_class is None:
52+
raise RuntimeError(
53+
"Unable to identify model to sync. Need to provide at least one object in `new_models`, provide `db_class`, or set `new_models` with a queryset like `db_class.objects.none()`."
54+
)
3955

4056
if fields is None:
4157
# Get a list of fields that aren't PKs and aren't editable (e.g. auto_add_now) for bulk_update

tests/tests.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,15 @@ def test_skip_updates(self):
210210
self.assertEqual(1, ret["stats"]["created"])
211211
self.assertEqual(1, ret["stats"]["deleted"])
212212

213+
def test_empty_new_models_class_detection_works(self):
214+
c1 = Company.objects.create(name="My Company LLC")
215+
216+
with self.assertRaises(RuntimeError):
217+
ret = bulk_sync(new_models=[], filters=None, key_fields=("name",))
218+
219+
ret = bulk_sync(new_models=[], filters=None, key_fields=("name",), db_class=Employee)
220+
ret = bulk_sync(new_models=Employee.objects.none(), filters=None, key_fields=("name",))
221+
213222

214223
class BulkCompareTests(TestCase):
215224
""" Test `bulk_compare` method """

0 commit comments

Comments
 (0)