A proxy to an insert or update query. :param columns: Only the specified columns will be synced back to the database when doing an update. For example: .. code-block:: python band = await Band.objects().first() b
(
self, columns: Optional[Sequence[Union[Column, str]]] = None
)
| 488 | ########################################################################### |
| 489 | |
| 490 | def save( |
| 491 | self, columns: Optional[Sequence[Union[Column, str]]] = None |
| 492 | ) -> Union[Insert, Update]: |
| 493 | """ |
| 494 | A proxy to an insert or update query. |
| 495 | |
| 496 | :param columns: |
| 497 | Only the specified columns will be synced back to the database |
| 498 | when doing an update. For example: |
| 499 | |
| 500 | .. code-block:: python |
| 501 | |
| 502 | band = await Band.objects().first() |
| 503 | band.popularity = 2000 |
| 504 | await band.save(columns=[Band.popularity]) |
| 505 | |
| 506 | If ``columns=None`` (the default) then all columns will be synced |
| 507 | back to the database. |
| 508 | |
| 509 | """ |
| 510 | cls = self.__class__ |
| 511 | |
| 512 | # New row - insert |
| 513 | if not self._exists_in_db: |
| 514 | return cls.insert(self).returning(cls._meta.primary_key) |
| 515 | |
| 516 | # Pre-existing row - update |
| 517 | if columns is None: |
| 518 | column_instances = [ |
| 519 | i for i in cls._meta.columns if not i._meta.primary_key |
| 520 | ] |
| 521 | else: |
| 522 | column_instances = [ |
| 523 | self._meta.get_column_by_name(i) if isinstance(i, str) else i |
| 524 | for i in columns |
| 525 | ] |
| 526 | |
| 527 | values: dict[Column, Any] = { |
| 528 | i: getattr(self, i._meta.name, None) for i in column_instances |
| 529 | } |
| 530 | |
| 531 | # Assign any `auto_update` values |
| 532 | if cls._meta.auto_update_columns: |
| 533 | auto_update_values = cls._meta.get_auto_update_values() |
| 534 | values.update(auto_update_values) |
| 535 | for column, value in auto_update_values.items(): |
| 536 | setattr(self, column._meta.name, value) |
| 537 | |
| 538 | return cls.update( |
| 539 | values, # type: ignore |
| 540 | # We've already included the `auto_update` columns, so no need |
| 541 | # to do it again: |
| 542 | use_auto_update=False, |
| 543 | ).where( |
| 544 | cls._meta.primary_key |
| 545 | == getattr(self, self._meta.primary_key._meta.name) |
| 546 | ) |
| 547 |