Skip to content

Commit 6dc37e8

Browse files
committed
[ADD] pg.query_ids: query large numbers of ids memory-safely
This is mainly the code that has been recently added to `orm.recompute_fields`, here we're making it re-usasble.
1 parent 09d18f5 commit 6dc37e8

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

src/util/pg.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1932,3 +1932,41 @@ def bulk_update_table(cr, table, columns, mapping, key_col="id"):
19321932
key_col=key_col,
19331933
)
19341934
cr.execute(query, [Json(mapping)])
1935+
1936+
1937+
class query_ids(named_cursor):
1938+
def __init__(self, cr, query, itersize=None):
1939+
self._cr = cr
1940+
self._tmp_tbl = "_upgrade_query_ids_{}".format(uuid.uuid4().hex)
1941+
cr.execute(
1942+
format_query(
1943+
cr,
1944+
"CREATE UNLOGGED TABLE {}(id) AS (WITH query AS ({}) SELECT * FROM query)",
1945+
self._tmp_tbl,
1946+
SQLStr(query),
1947+
)
1948+
)
1949+
self._len = cr.rowcount
1950+
cr.execute(
1951+
format_query(
1952+
cr, "ALTER TABLE {} ADD CONSTRAINT {} PRIMARY KEY (id)", self._tmp_tbl, "pk_{}_id".format(self._tmp_tbl)
1953+
)
1954+
)
1955+
super(query_ids, self).__init__(cr, itersize)
1956+
self.execute(format_query(cr, "SELECT id FROM {} ORDER BY id", self._tmp_tbl))
1957+
1958+
def __len__(self):
1959+
return self._len
1960+
1961+
def __iter__(self):
1962+
return (id_ for (id_,) in super(query_ids, self).__iter__())
1963+
1964+
def __exit__(self, exc_type, exc_value, traceback):
1965+
self._cr.execute(format_query(self._cr, "DROP TABLE IF EXISTS {}", self._tmp_tbl))
1966+
self._cr = None
1967+
return super(query_ids, self).__exit__(exc_type, exc_value, traceback)
1968+
1969+
def __del__(self):
1970+
if self._cr:
1971+
self._cr.execute(format_query(self._cr, "DROP TABLE IF EXISTS {}", self._tmp_tbl))
1972+
return super(query_ids, self).__del__()

0 commit comments

Comments
 (0)