使用 python psycopg2 对 postgres 中的巨大文本值进行流式传输或分块(单行、单列)

问题描述 投票:0回答:1

我正在使用 select 语句动态创建一个超过 1GB 的巨大 SQL 文本。在执行 SQL 读取列(一)值(生成的 SQL)时,postgres 无法返回输出。

SQL Error [54000]: ERROR: out of memory
  Detail: Cannot enlarge string buffer containing 1073741741 bytes by 95 more bytes.

输出只有一行一列,即不是n行,只是一个巨大的字符串值。因此,我无法使用 fetchmany 或游标的其他选项,因为数据(一列)不适合。下面的内容已经就位,但在这种情况下没有帮助。

with self.getConnection() as conn:
                with conn.cursor(name=cur_name) as cursor:
                    cursor.itersize = chunksize
                    cursor.execute(sql)
                    while True:
                        results = cursor.fetchmany(chunksize)
.
.
.

我尝试将列值存储为大对象。即

CREATE TABLE lo_sql_data (
    id bigserial not null ,
    valuation_date date NOT NULL,
    dynamic_sql oid NULL,
    CONSTRAINT lo_sql_data_pkey PRIMARY KEY (id)
)

insert into lo_sql_data (valuation_date, dynamic_sql )   
SELECT '2023-08-31'::date,  lo_from_bytea(0, format(
$f$
SELECT <my dynamic query which generates a SQL very big>
$f$
)::bytea)
.
.

以上对于较小的动态 SQL 输出值效果很好,但任何大于缓冲区大小的内容都会引发上述错误。

限制是服务器端(postgres),我知道我们无法增加字符串缓冲区值。

有没有一种方法可以在生成字符串值时对其进行流式传输并将其传递给客户端(Python),然后在Python中我可以合并并生成单个字符串?

或者有没有其他方法可以让我从服务器获取动态sql(稍后执行)的值?

python postgresql streaming psycopg2
1个回答
0
投票

这种做法注定是失败的。您不能返回超过 1GB 的字符串,因为这是 PostgreSQL 中任何数据类型的大小的硬性限制。另外,超过 1GB 的 SQL 语句不会有任何帮助,因为协议消息的限制也是 1GB,因此您无法发送那么大的语句。

编写更合理的SQL语句。也许你的数据模型有问题。

© www.soinside.com 2019 - 2024. All rights reserved.