@@ -362,7 +362,9 @@ class iter_browse(object):
362362
363363 :param model: the model to iterate
364364 :type model: :class:`odoo.model.Model`
365- :param list(int) ids: list of IDs of the records to iterate
365+ :param iterable(int) ids: iterable of IDs of the records to iterate
366+ :param str query: alternative to ids, SQL query that can produce them.
367+ Can also be a DML statement with a RETURNING clause.
366368 :param int chunk_size: number of records to load in each iteration chunk, `200` by
367369 default
368370 :param logger: logger used to report the progress, by default
@@ -375,23 +377,35 @@ class iter_browse(object):
375377 See also :func:`~odoo.upgrade.util.orm.env`
376378 """
377379
378- __slots__ = ("_chunk_size" , "_cr_uid" , "_it" , "_logger" , "_model" , "_patch" , "_size" , "_strategy" )
380+ __slots__ = ("_chunk_size" , "_cr_uid" , "_ids" , " _it" , "_logger" , "_model" , "_patch" , "_query " , "_size" , "_strategy" )
379381
380382 def __init__ (self , model , * args , ** kw ):
381383 assert len (args ) in [1 , 3 ] # either (cr, uid, ids) or (ids,)
382384 self ._model = model
383385 self ._cr_uid = args [:- 1 ]
384- ids = args [- 1 ]
385- self ._size = len (ids )
386+ self ._ids = args [- 1 ]
387+ self ._size = kw .pop ("size" , None )
388+ self ._query = kw .pop ("query" , None )
386389 self ._chunk_size = kw .pop ("chunk_size" , 200 ) # keyword-only argument
387390 self ._logger = kw .pop ("logger" , _logger )
388391 self ._strategy = kw .pop ("strategy" , "flush" )
389392 assert self ._strategy in {"flush" , "commit" }
390393 if kw :
391394 raise TypeError ("Unknown arguments: %s" % ", " .join (kw ))
392395
396+ if not (self ._ids is None ) ^ (self ._query is None ):
397+ raise TypeError ("Must be initialized using exactly one of `ids` or `query`" )
398+
399+ if self ._query :
400+ self ._ids = query_ids (self ._model .env .cr , self ._query , itersize = self ._chunk_size )
401+
402+ if not self ._size :
403+ try :
404+ self ._size = len (self ._ids )
405+ except TypeError :
406+ raise ValueError ("When passing ids as a generator, the size kwarg is mandatory" )
393407 self ._patch = None
394- self ._it = chunks (ids , self ._chunk_size , fmt = self ._browse )
408+ self ._it = chunks (self . _ids , self ._chunk_size , fmt = self ._browse )
395409
396410 def _browse (self , ids ):
397411 next (self ._end (), None )
0 commit comments