Skip to content

Commit 060b1a3

Browse files
committed
[IMP] orm: iter_browse.create() accept generator or query as values
Done to be able to create millions of records memory-efficiently.
1 parent a40dde7 commit 060b1a3

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

src/util/orm.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,19 @@ def get_ids():
502502

503503
self._ids = get_ids()
504504

505+
def _values_query(self, query):
506+
cr = self._model.env.cr
507+
cr.execute(format_query(cr, "WITH query AS ({}) SELECT count(*) FROM query", query))
508+
size = cr.fetchone()[0]
509+
510+
def get_values():
511+
with named_cursor(cr, itersize=self._chunk_size) as ncr:
512+
ncr.execute(query)
513+
for row in ncr.iterdict():
514+
yield row
515+
516+
return size, get_values()
517+
505518
def _browse(self, ids):
506519
next(self._end(), None)
507520
args = self._cr_uid + (list(ids),)
@@ -593,6 +606,7 @@ def create(self, values, **kw):
593606
`True` from Odoo 12 and above
594607
"""
595608
multi = kw.pop("multi", version_gte("saas~11.5"))
609+
size = kw.pop("size", None)
596610
if kw:
597611
raise TypeError("Unknown arguments: %s" % ", ".join(kw))
598612

@@ -605,7 +619,15 @@ def create(self, values, **kw):
605619
if self._strategy == "multiprocessing" and not multi:
606620
raise ValueError("The multiprocessing strategy only supports the multi version of `create`")
607621

608-
size = len(values)
622+
if isinstance(values, SQLStr):
623+
size, values = self._values_query(values)
624+
625+
if size is None:
626+
try:
627+
size = len(values)
628+
except TypeError:
629+
raise ValueError("When passing values as a generator, the size kwarg is mandatory")
630+
609631
chunk_size = self._superchunk_size if self._strategy == "multiprocessing" else self._chunk_size
610632
it = chunks(values, chunk_size, fmt=list)
611633
if self._logger:

0 commit comments

Comments
 (0)