Return async iterable generator for all rows from a database for given model. Passing args and/or kwargs is a shortcut and equals to calling `filter(*args, **kwargs).iterate()`. If there are no rows meeting the criteria an empty async generator is returned.
( # noqa: A003
self,
*args: Any,
**kwargs: Any,
)
| 1290 | return result_rows |
| 1291 | |
| 1292 | async def iterate( # noqa: A003 |
| 1293 | self, |
| 1294 | *args: Any, |
| 1295 | **kwargs: Any, |
| 1296 | ) -> AsyncGenerator["T", None]: |
| 1297 | """ |
| 1298 | Return async iterable generator for all rows from a database for given model. |
| 1299 | |
| 1300 | Passing args and/or kwargs is a shortcut and equals to calling |
| 1301 | `filter(*args, **kwargs).iterate()`. |
| 1302 | |
| 1303 | If there are no rows meeting the criteria an empty async generator is returned. |
| 1304 | |
| 1305 | :param kwargs: fields names and proper value types |
| 1306 | :type kwargs: Any |
| 1307 | :return: asynchronous iterable generator of returned models |
| 1308 | :rtype: AsyncGenerator[Model] |
| 1309 | """ |
| 1310 | |
| 1311 | if self._prefetch_related: |
| 1312 | raise QueryDefinitionError( |
| 1313 | "Prefetch related queries are not supported in iterators" |
| 1314 | ) |
| 1315 | |
| 1316 | if kwargs or args: |
| 1317 | async for result in self.filter(*args, **kwargs).iterate(): |
| 1318 | yield result |
| 1319 | return |
| 1320 | |
| 1321 | expr = self.build_select_expression() |
| 1322 | |
| 1323 | rows: list = [] |
| 1324 | last_primary_key = None |
| 1325 | pk_alias = self.model.get_column_alias(self.model_config.pkname) |
| 1326 | # Single shared cache across all yielded chunks so 1-row chunks |
| 1327 | # (the common iterate case) still amortize the plan build. |
| 1328 | plan_cache: dict = {} |
| 1329 | |
| 1330 | # Server-side cursor (asyncpg/aiomysql) requires an open transaction, |
| 1331 | # which AUTOCOMMIT does not provide. |
| 1332 | async with self.model_config.database.get_query_executor( |
| 1333 | transactional=True |
| 1334 | ) as executor: |
| 1335 | async for row in executor.iterate(expr): |
| 1336 | current_primary_key = row[pk_alias] |
| 1337 | if last_primary_key == current_primary_key or last_primary_key is None: |
| 1338 | last_primary_key = current_primary_key |
| 1339 | rows.append(row) |
| 1340 | continue |
| 1341 | |
| 1342 | yield (await self._process_query_result_rows(rows, plan_cache))[0] |
| 1343 | last_primary_key = current_primary_key |
| 1344 | rows = [row] |
| 1345 | |
| 1346 | if rows: |
| 1347 | yield (await self._process_query_result_rows(rows, plan_cache))[0] |
| 1348 | |
| 1349 | async def create(self, **kwargs: Any) -> "T": |