【问题标题】:How to create a json file from postgres table with parameters as a filename如何使用参数作为文件名从 postgres 表创建 json 文件
【发布时间】:2021-11-08 02:56:29
【问题描述】:

有什么方法可以让我从 postgres 表中创建一个 json 文件

正如我所做的那样使用

 copy to

但是当我在要调度的 postgres 函数中创建时,它无法将参数捕获为文件名

copy  v_originaltext to '/var/lib/postgresql/sftp/smrptesting1.json';

【问题讨论】:

    标签: json postgresql file copyto


    【解决方案1】:

    您可能会通过几种不同的方式完成您想要做的事情,尽管这两种方式都需要您 GRANT 组合 pg_write_server_files 和/或 pg_execute_server_program到执行角色/用户。

    方法1:使用动态SQL(使用pg_write_server_files

    在这里,您可以推断使用 COPY 命令的初始计划,并更改

    COPY v_originaltext to '/var/lib/postgresql/sftp/smrptesting1.json';
    

    改为在您要执行的功能块中声明一个 SQL 字符串变量 (v_sql),即类似

    CREATE OR REPLACE FUNCTION json_putter(_parameters TEXT)
    RETURNS VOID
    LANGUAGE plpgsql
    AS $function$
    DECLARE
        v_sql TEXT DEFAULT NULL;
        v_originaltext JSONB;
        v_filename TEXT;
    BEGIN
        -- < ... code to populate v_originaltext here ... >
        v_filename := '/var/lib/postgresql/sftp/' || _parameters || '.json';
        v_sql := 'COPY $1 TO $2';
        
        EXECUTE v_sql USING v_originaltext, v_filename;
    

    -- 或者,用文字单引号:

        v_sql := 'COPY (SELECT v_originaltext) TO ' || CHR(39) || v_filename || CHR(39);
        EXECUTE v_sql;
    END
    $function$
    

    这将构建 COPY 语句,就像您从客户端手动运行一样。

    方法2:使用服务器端psql命令(带pg_execute_server_program

    您可以直接从 psql 命令输出 json,并将标准输出重定向到您从参数生成的文件描述符。

    为了实现这一点,为简单起见,您可能需要创建两个原子函数:

    • 充当包装器以生成 v_originaltext 的值 [例如。 fx_originaltext(_parameters => text)]
    • 一个将使用 COPY ... FROM PROGRAM 实用程序通过 psql 运行通用命令并使用临时表或类似工具使用标准输出的命令:

    --

    CREATE OR REPLACE FUNCTION psql_runner(_function TEXT, _parameters TEXT)
    
    RETURNS VOID
    LANGUAGE plpgsql
    AS $function$
    DECLARE
        v_filename TEXT;
    BEGIN
        v_filename := '/var/lib/postgresql/sftp/' || _parameters || '.json';
        CREATE TEMP TABLE _out ( stdout text );
        COPY _out FROM PROGRAM ('psql -tq -c "SELECT ' || _function || '(_parameters :=' || quote_literal(_parameters) || ') " > ' || v_filename);
    END
    $function$
    

    值得注意的是,第二种方法需要更大范围的权限,并且根据您使用的 postgres 版本,可能需要像第一种方法一样将 COPY 作为动态 SQL 执行。

    【讨论】:

    • 非常感谢,抱歉回复晚了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多