如何从PostgreSQL查询到木地板文件流式传输超出内存容量的数据?

问题描述

我有以下代码,该代码查询约50万行的数据库。并在命中rows = cur.fetchall()时抛出SIGKILL。我试图遍历游标而不是将其全部加载到行中,但是它似乎仍然会引起OOM问题。

无论表的大小如何,我如何才能从数据库中获取所有数据并将其安全地转换为实木复合地板文件?

def get_parquet_for_dataset_id(self,dataset,lob,max_dt):
        query = _table_query(lob,table_name,max_dt)
        conn = self.conns[lob]

        with conn:
            with conn.cursor(cursor_factory=extras.RealDictCursor) as cur:
                cur.execute(query)

                rows = cur.fetchall()

                table = rows_to_table(rows)
                pq_bytes = io.BytesIO()
                pq.write_table(table,pq_bytes)
                _ = pq_bytes.seek(0)

                return pq_bytes;

解决方法

服务器端游标,请参见here

执行数据库查询时,Psycopg游标通常会获取后端返回的所有记录,并将它们转移到客户端进程。如果查询返回了大量数据,则客户端将按比例分配大量内存。

如果数据集太大而无法在客户端实际处理,则可以创建服务器端游标。使用这种游标,可以仅将受控量的数据传输到客户端,从而可以检查大型数据集而无需将其完全保留在内存中。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...