Allow upserting rows with existing_pk even if they do not exist. (#889)

* Allow for __force_save__ in Model.upsert() method to save the models despite they already have a pk set. On integrity Error proceed to update the model, so in worst case two db calls will be made.

* Fix coverage

* Change implementation to checking if the row exists as postgres leaves hanging invalid transaction on integrity error. On force_save always check if row exists and then save/update (so always two queries).
This commit is contained in:
collerek
2022-10-21 13:32:36 +02:00
committed by GitHub
parent f94e507d70
commit 4fa0205598
4 changed files with 157 additions and 1 deletions

View File

@ -305,7 +305,7 @@ class SavePrepareMixin(RelationMixin, AliasMixin):
if (
save_all or not instance.pk or not instance.saved
) and not instance.__pk_only__:
await instance.upsert()
await instance.upsert(__force_save__=True)
if relation_field and relation_field.is_multi:
await instance._upsert_through_model(
instance=instance,

View File

@ -37,6 +37,15 @@ class Model(ModelRow):
:return: saved Model
:rtype: Model
"""
force_save = kwargs.pop("__force_save__", False)
if force_save:
expr = self.Meta.table.select().where(self.pk_column == self.pk)
row = await self.Meta.database.fetch_one(expr)
if not row:
return await self.save()
return await self.update(**kwargs)
if not self.pk:
return await self.save()
return await self.update(**kwargs)