plpython3: 一个函数 return 一个 'class' 或 'generator' 对象可以查询吗

plpython3: can a function return a 'class' or 'generator' object to a query

我是 运行 一个带有 postgres 图像的 docker 容器。该图像包括 python3、pandas 和 networkx。这种组合允许我在 postgres 环境中从数据库数据构建一个图表。

我希望能够通过对数据库的远程查询来检索图形。该图作为 GD 中的条目存在,类型为 class。如果我 return 它作为类型 text 如下面的代码,我得到字符串 Graph with 40 nodes and 20 edges.

drop function if exists GD_retrieve();
create or replace function GD_retrieve()
    returns text
language plpython3u as
$function$
    return GD['recon_G']
$function$;

select * from GD_retrieve();

我想也许 运行 转换为文本可能有效,例如将图表转换为 graphml(一种文本格式)并 return 作为生成器。

drop function if exists GD_retrieve();
create or replace function GD_retrieve()
    returns text
language plpython3u as
$function$
    import networkx as nx
    graphml = nx.generate_graphml(GD['recon_G'])
    return graphml
$function$;

这给出了一个字符串 '<generator object generate_graphml at 0x7fe78b6b2480>' 但如果我使用 cytoscape 格式:

drop function if exists GD_retrieve();
create or replace function GD_retrieve()
    returns text
language plpython3u as
$function$
    import networkx as nx
    graph_cyto = nx.cytoscape_data(GD['recon_G'])
    return graph_cyto
$function$;

我得到一个很长的字符串,其中包含可以解析或导入到 networkx 本地或 cytoscape 本身的所有数据。不可怕但不优雅。有更好的方法吗?

另一种方法是:

drop function if exists GD_retrieve();
create or replace function GD_retrieve()
    returns text[]
language plpython3u as
$function$
    import networkx as nx
    graph = GD['recon_G']  <-- networkx graph stored in global dict
    graph_alt = nx.generate_graphml(graph)  <-- returns a generator
    graphml_ser = []
    for item in graph_alt:
        graphml_ser.extend([item]) <-- use generator to build up a long string
    return graphml_ser  <-- returns a text array 
$function$;

因此,如果我发送查询 select * from GD_retrieve();,我会返回一个 graphml 文本字符串,本质上是一个序列化的 XML 文件,其中包含与图形特别相关的元素。再次不优雅,但它有效。