Combination of create and get methods. Tries to get a row meeting the criteria for kwargs and if `NoMatch` exception is raised it creates a new one with given kwargs and _defaults. If a concurrent caller wins the race and creates a matching row betw
(
self,
_defaults: Optional[dict[str, Any]] = None,
*args: Any,
**kwargs: Any,
)
| 1194 | return processed_rows[0] # type: ignore |
| 1195 | |
| 1196 | async def get_or_create( |
| 1197 | self, |
| 1198 | _defaults: Optional[dict[str, Any]] = None, |
| 1199 | *args: Any, |
| 1200 | **kwargs: Any, |
| 1201 | ) -> tuple["T", bool]: |
| 1202 | """ |
| 1203 | Combination of create and get methods. |
| 1204 | |
| 1205 | Tries to get a row meeting the criteria for kwargs |
| 1206 | and if `NoMatch` exception is raised |
| 1207 | it creates a new one with given kwargs and _defaults. |
| 1208 | |
| 1209 | If a concurrent caller wins the race and creates a matching row |
| 1210 | between this call's ``get`` and ``create``, the ``create`` raises |
| 1211 | ``sqlalchemy.exc.IntegrityError`` and ``get`` is retried once. |
| 1212 | If the retry still finds no row, the original ``IntegrityError`` is |
| 1213 | re-raised because the violation isn't a race but a legitimate |
| 1214 | constraint conflict (e.g. a different unique key). |
| 1215 | |
| 1216 | Passing a criteria is actually calling filter(*args, **kwargs) method described |
| 1217 | below. |
| 1218 | |
| 1219 | :param kwargs: fields names and proper value types |
| 1220 | :type kwargs: Any |
| 1221 | :param _defaults: default values for creating object |
| 1222 | :type _defaults: Optional[dict[str, Any]] |
| 1223 | :return: model instance and a boolean |
| 1224 | :rtype: tuple("T", bool) |
| 1225 | """ |
| 1226 | try: |
| 1227 | return await self.get(*args, **kwargs), False |
| 1228 | except NoMatch: |
| 1229 | pass |
| 1230 | |
| 1231 | _defaults = _defaults or {} |
| 1232 | try: |
| 1233 | return await self.create(**{**kwargs, **_defaults}), True |
| 1234 | except sqlalchemy.exc.IntegrityError as integrity_error: |
| 1235 | try: |
| 1236 | return await self.get(*args, **kwargs), False |
| 1237 | except NoMatch: |
| 1238 | raise integrity_error from None |
| 1239 | |
| 1240 | async def update_or_create(self, **kwargs: Any) -> "T": |
| 1241 | """ |