file_fdw 模块提供外部数据包装器 file_fdw,它可用于访问服务器文件系统中的数据文件,或者在服务器上执行程序并读取其输出。数据文件或程序输出必须采用 COPY FROM 可以读取的格式;详情参见 COPY。目前对数据文件的访问是只读的。
使用该包装器创建的外表可以具有以下选项:
filename
指定要读取的文件。相对路径相对于数据目录。必须指定 filename 或 program 之一,但两者不能同时指定。
program
指定要执行的命令。该命令的标准输出将如同使用了 COPY FROM PROGRAM 一样被读取。必须指定 program 或 filename 之一,但两者不能同时指定。
format
指定数据格式,与 COPY 的 FORMAT 选项相同。
header
指定数据是否带有标题行,与 COPY 的 HEADER 选项相同。
delimiter
指定数据分隔字符,与 COPY 的 DELIMITER 选项相同。
quote
指定数据引号字符,与 COPY 的 QUOTE 选项相同。
escape
指定数据转义字符,与 COPY 的 ESCAPE 选项相同。
null
指定数据的空串,与 COPY 的 NULL 选项相同。
default
指定表示默认值的字符串,与 COPY 的 DEFAULT 选项相同。
encoding
指定数据编码,与 COPY 的 ENCODING 选项相同。
on_error
指定将列的输入值转换为其数据类型时遇到错误的处理方式,与 COPY 的 ON_ERROR 选项相同。
reject_limit
指定将列的输入值转换为其数据类型时可容忍的最大错误数,与 COPY 的 REJECT_LIMIT 选项相同。
log_verbosity
指定 file_fdw 发出消息的数量,与 COPY 的 LOG_VERBOSITY 选项相同。
请注意,COPY 允许 HEADER 等选项在书写时不带对应值,而外表选项语法要求任何情况下都必须提供值。要激活通常不带值书写的 COPY 选项,可以传入值 TRUE,因为所有这类选项都是布尔值。
使用该包装器创建的外表的列可以具有以下选项:
force_not_null
这是一个布尔选项。如果为真,它指定该列的值不与空串匹配(即表级的 null 选项)。这与在 COPY 的 FORCE_NOT_NULL 选项中列出该列具有相同效果。
force_null
这是一个布尔选项。如果为真,它指定该列中与空串匹配的值即使被引号包裹,也返回为 NULL。没有该选项时,只有未被引号包裹且与空串匹配的值才返回为 NULL。这与在 COPY 的 FORCE_NULL 选项中列出该列具有相同效果。
COPY 的 FORCE_QUOTE 选项目前不受 file_fdw 支持。
这些选项只能为外表或其列指定,不能在 file_fdw 外部数据包装器的选项中指定,也不能在使用该包装器的服务器或用户映射的选项中指定。
出于安全考虑,更改表级选项需要是超级用户,或拥有 pg_read_server_files 角色的特权(使用文件名时)或 pg_execute_server_program 角色的特权(使用程序时):只有特定的用户才能控制读取哪个文件或运行哪个程序。原则上可以允许普通用户更改其他选项,但目前不支持这样做。
指定 program 选项时请记住,该选项字符串由 shell 执行。如果你需要向命令传递任何来自不受信任来源的参数,必须小心地去除或转义任何对 shell 可能有特殊含义的字符。出于安全考虑,最好使用固定的命令字符串,或者至少避免在其中传递任何用户输入。
对于使用 file_fdw 的外表,EXPLAIN 会显示要读取的文件名或要运行的程序名。对于文件,除非指定了 COSTS OFF,还会显示文件大小(以字节为单位)。
Example F.1. 为 PostgreSQL CSV 日志创建外表
file_fdw 的一个明显用途是将 PostgreSQL 活动日志作为表供查询。要做到这一点,首先你必须 将日志记录到 CSV 文件,这里我们将其命名为 pglog.csv。首先,将 file_fdw 作为扩展安装:
CREATE EXTENSION file_fdw;
然后创建一个外部服务器:
CREATE SERVER pglog FOREIGN DATA WRAPPER file_fdw;
现在就可以创建外部数据表了。使用 CREATE FOREIGN TABLE 命令时,你需要定义表的列、CSV 文件名及其格式:
CREATE FOREIGN TABLE pglog ( log_time timestamp(3) with time zone, user_name text, database_name text, process_id integer, connection_from text, session_id text, session_line_num bigint, command_tag text, session_start_time timestamp with time zone, virtual_transaction_id text, transaction_id bigint, error_severity text, sql_state_code text, message text, detail text, hint text, internal_query text, internal_query_pos integer, context text, query text, query_pos integer, location text, application_name text, backend_type text, leader_pid integer, query_id bigint ) SERVER pglog OPTIONS ( filename 'log/pglog.csv', format 'csv' );
大功告成 — 现在你可以直接查询日志了。当然,在生产环境中,你还需要定义某种处理日志轮转的方法。
Example F.2. 创建带列选项的外表
要为列设置 force_null 选项,使用 OPTIONS 关键字。
CREATE FOREIGN TABLE films ( code char(5) NOT NULL, title text NOT NULL, rating text OPTIONS (force_null 'true') ) SERVER film_server OPTIONS ( filename 'films/db.csv', format 'csv' );