如何使用参数作为文件名从 postgres table 创建一个 json 文件
How to create a json file from postgres table with parameters as a filename
我有什么方法可以从 postgres table
创建一个 json 文件
正如我使用
创建的
copy to
但是当我在一个postgres函数中创建被调度时,它无法捕获参数作为文件名
copy v_originaltext to '/var/lib/postgresql/sftp/smrptesting1.json';
您可能会通过几种不同的方式完成您想要做的事情,尽管这两种方式都需要您 GRANT pg_write_server_files and/or pg_execute_server_program 到执行 role/user.
方法 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 TO ';
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 语句,就像您从客户端手动 运行ning 一样。
方法二:使用服务器端psql命令(使用pg_execute_server_program)
您可以直接从 psql 命令输出 json,并将标准输出重定向到您从参数生成的文件描述符。
为了实现这个,为了简单起见,您可能想要创建两个原子函数:
- 作为包装器生成 v_originaltext 值的一个 [例如fx_originaltext(_parameters => 文本)]
- 将 运行 使用 COPY ... FROM PROGRAM 实用程序通过 psql 执行通用命令并使用临时 table 或类似的标准输出:
--
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。
我有什么方法可以从 postgres table
创建一个 json 文件正如我使用
创建的 copy to
但是当我在一个postgres函数中创建被调度时,它无法捕获参数作为文件名
copy v_originaltext to '/var/lib/postgresql/sftp/smrptesting1.json';
您可能会通过几种不同的方式完成您想要做的事情,尽管这两种方式都需要您 GRANT pg_write_server_files and/or pg_execute_server_program 到执行 role/user.
方法 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 TO ';
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 语句,就像您从客户端手动 运行ning 一样。
方法二:使用服务器端psql命令(使用pg_execute_server_program)
您可以直接从 psql 命令输出 json,并将标准输出重定向到您从参数生成的文件描述符。
为了实现这个,为了简单起见,您可能想要创建两个原子函数:
- 作为包装器生成 v_originaltext 值的一个 [例如fx_originaltext(_parameters => 文本)]
- 将 运行 使用 COPY ... FROM PROGRAM 实用程序通过 psql 执行通用命令并使用临时 table 或类似的标准输出:
--
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。