| 206 | ) |
| 207 | |
| 208 | def chunks(size): # type: ignore |
| 209 | while True: |
| 210 | yield_per = size |
| 211 | |
| 212 | context.partials = {} |
| 213 | |
| 214 | if yield_per: |
| 215 | fetch = cursor.fetchmany(yield_per) |
| 216 | |
| 217 | if not fetch: |
| 218 | break |
| 219 | else: |
| 220 | fetch = cursor._raw_all_rows() |
| 221 | |
| 222 | if single_entity: |
| 223 | proc = process[0] |
| 224 | rows = [proc(row) for row in fetch] |
| 225 | else: |
| 226 | rows = [ |
| 227 | tuple([proc(row) for proc in process]) for row in fetch |
| 228 | ] |
| 229 | |
| 230 | # if we are the originating load from a query, meaning we |
| 231 | # aren't being called as a result of a nested "post load", |
| 232 | # iterate through all the collected post loaders and fire them |
| 233 | # off. Previously this used to work recursively, however that |
| 234 | # prevented deeply nested structures from being loadable |
| 235 | if is_top_level: |
| 236 | if yield_per: |
| 237 | # if using yield per, memoize the state of the |
| 238 | # collection so that it can be restored |
| 239 | top_level_post_loads = list( |
| 240 | context.post_load_paths.items() |
| 241 | ) |
| 242 | |
| 243 | while context.post_load_paths: |
| 244 | post_loads = list(context.post_load_paths.items()) |
| 245 | context.post_load_paths.clear() |
| 246 | for path, post_load in post_loads: |
| 247 | post_load.invoke(context, path) |
| 248 | |
| 249 | if yield_per: |
| 250 | context.post_load_paths.clear() |
| 251 | context.post_load_paths.update(top_level_post_loads) |
| 252 | |
| 253 | yield rows |
| 254 | |
| 255 | if not yield_per: |
| 256 | break |
| 257 | |
| 258 | if context.execution_options.get("prebuffer_rows", False): |
| 259 | # this is a bit of a hack at the moment. |