Skip to content

Commit 7a16d08

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 be0b303 commit 7a16d08

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),)
@@ -589,6 +602,7 @@ def create(self, values, **kw):
589602
`True` from Odoo 12 and above
590603
"""
591604
multi = kw.pop("multi", version_gte("saas~11.5"))
605+
size = kw.pop("size", None)
592606
if kw:
593607
raise TypeError("Unknown arguments: %s" % ", ".join(kw))
594608

@@ -601,7 +615,15 @@ def create(self, values, **kw):
601615
if self._strategy == "multiprocessing" and not multi:
602616
raise ValueError("The multiprocessing strategy only supports the multi version of `create`")
603617

604-
size = len(values)
618+
if isinstance(values, SQLStr):
619+
size, values = self._values_query(values)
620+
621+
if size is None:
622+
try:
623+
size = len(values)
624+
except TypeError:
625+
raise ValueError("When passing values as a generator, the size kwarg is mandatory")
626+
605627
it = chunks(values, self._chunk_size, fmt=list)
606628
if self._logger:
607629
sz = (size + self._chunk_size - 1) // self._chunk_size

0 commit comments

Comments
 (0)