@@ -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 bool yield_chunks: when iterating, yield records in chunks of `chunk_size` instead of one by one.
@@ -377,14 +379,27 @@ class iter_browse(object):
377379 See also :func:`~odoo.upgrade.util.orm.env`
378380 """
379381
380- __slots__ = ("_chunk_size" , "_cr_uid" , "_it" , "_logger" , "_model" , "_patch" , "_size" , "_strategy" , "_yield_chunks" )
382+ __slots__ = (
383+ "_chunk_size" ,
384+ "_cr_uid" ,
385+ "_ids" ,
386+ "_it" ,
387+ "_logger" ,
388+ "_model" ,
389+ "_patch" ,
390+ "_query" ,
391+ "_size" ,
392+ "_strategy" ,
393+ "_yield_chunks" ,
394+ )
381395
382396 def __init__ (self , model , * args , ** kw ):
383397 assert len (args ) in [1 , 3 ] # either (cr, uid, ids) or (ids,)
384398 self ._model = model
385399 self ._cr_uid = args [:- 1 ]
386- ids = args [- 1 ]
387- self ._size = len (ids )
400+ self ._ids = args [- 1 ]
401+ self ._size = kw .pop ("size" , None )
402+ self ._query = kw .pop ("query" , None )
388403 self ._chunk_size = kw .pop ("chunk_size" , 200 ) # keyword-only argument
389404 self ._yield_chunks = kw .pop ("yield_chunks" , False )
390405 self ._logger = kw .pop ("logger" , _logger )
@@ -393,8 +408,19 @@ def __init__(self, model, *args, **kw):
393408 if kw :
394409 raise TypeError ("Unknown arguments: %s" % ", " .join (kw ))
395410
411+ if not (self ._ids is None ) ^ (self ._query is None ):
412+ raise TypeError ("Must be initialized using exactly one of `ids` or `query`" )
413+
414+ if self ._query :
415+ self ._ids = query_ids (self ._model .env .cr , self ._query , itersize = self ._chunk_size )
416+
417+ if not self ._size :
418+ try :
419+ self ._size = len (self ._ids )
420+ except TypeError :
421+ raise ValueError ("When passing ids as a generator, the size kwarg is mandatory" )
396422 self ._patch = None
397- self ._it = chunks (ids , self ._chunk_size , fmt = self ._browse )
423+ self ._it = chunks (self . _ids , self ._chunk_size , fmt = self ._browse )
398424
399425 def _browse (self , ids ):
400426 next (self ._end (), None )
0 commit comments