add save_all, some optimizations

This commit is contained in:
collerek
2021-03-26 16:28:34 +01:00
parent 8f60593123
commit 5a3b170d06
3 changed files with 30 additions and 5 deletions

View File

@ -1,9 +1,19 @@
# 0.10.2
## Features
* `save_related(follow=False)` now accept also second argument `save_related(follow=False, save_all=False)`.
By default so with `save_all=False` `ormar` only upserts models that are no saved (so new or updated ones),
with `save_all=True` all related models are saved, regardless of `saved` status, which might be usefull if updated
models comes from api call, so are not changed in backend.
## Fixes
* Fix improper relation field resolution in `QuerysetProxy` if fk column has different database alias.
## Other
* Performance optimizations
# 0.10.1

View File

@ -101,7 +101,11 @@ class Model(ModelRow):
return self
async def save_related( # noqa: CCR001
self, follow: bool = False, visited: Set = None, update_count: int = 0
self,
follow: bool = False,
save_all: bool = False,
visited: Set = None,
update_count: int = 0,
) -> int: # noqa: CCR001
"""
Triggers a upsert method on all related models
@ -145,6 +149,7 @@ class Model(ModelRow):
update_count, visited = await self._update_and_follow(
rel=rel,
follow=follow,
save_all=save_all,
visited=visited,
update_count=update_count,
)
@ -152,14 +157,18 @@ class Model(ModelRow):
else:
rel = getattr(self, related)
update_count, visited = await self._update_and_follow(
rel=rel, follow=follow, visited=visited, update_count=update_count
rel=rel,
follow=follow,
save_all=save_all,
visited=visited,
update_count=update_count,
)
visited.add(rel.__class__)
return update_count
@staticmethod
async def _update_and_follow(
rel: "Model", follow: bool, visited: Set, update_count: int
rel: "Model", follow: bool, save_all: bool, visited: Set, update_count: int
) -> Tuple[int, Set]:
"""
Internal method used in save_related to follow related models and update numbers
@ -181,9 +190,12 @@ class Model(ModelRow):
"""
if follow and rel.__class__ not in visited:
update_count = await rel.save_related(
follow=follow, visited=visited, update_count=update_count
follow=follow,
save_all=save_all,
visited=visited,
update_count=update_count,
)
if not rel.saved:
if not rel.saved or save_all:
await rel.upsert()
update_count += 1
return update_count, visited

View File

@ -110,6 +110,9 @@ async def test_saving_many_to_many():
count = await hq.save_related()
assert count == 0
count = await hq.save_related(save_all=True)
assert count == 2
hq.nicks[0].name = "Kabucha"
hq.nicks[1].name = "Kabucha2"
assert not hq.nicks[0].saved