F.15. file_fdw — 访问服务器文件系统中的数据文件 #

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

指定数据 NULL 字符串,与 COPY 的 NULL 选项相同。

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

这是一个布尔型选项。如果为 true,则指定列的值不应与 NULL 字符串匹配(即,表级别的 null 选项)。这与在 COPY 的 FORCE_NOT_NULL 选项中列出该列的效果相同。

force_null

这是一个布尔型选项。如果为 true,则指定与 NULL 字符串匹配的列值即使被引用也将返回为 NULL。没有此选项,只有未被引用的匹配 NULL 字符串的值才会被返回为 NULL。这与在 COPY 的 FORCE_NULL 选项中列出该列的效果相同。

file_fdw 目前不支持 COPY 的 FORCE_QUOTE 选项。

这些选项只能为外部表或其列指定,不能在 file_fdw 外部数据包装器的选项中指定,也不能在使用此包装器的服务器或用户映射的选项中指定。

出于安全原因,更改表级别的选项需要是超级用户或具有 pg_read_server_files(使用文件名)或 pg_execute_server_program(使用程序)角色的特权:只有特定用户才能控制读取哪个文件或运行哪个程序。原则上,普通用户也可以被允许更改其他选项,但这目前不支持。

指定 program 选项时,请记住选项字符串由 shell 执行。如果您需要将任何参数传递给命令,并且这些参数来自不受信任的来源,您必须小心地删除或转义任何可能对 shell 具有特殊含义的字符。出于安全原因,最好使用固定的命令字符串,或者至少避免在其中传递任何用户输入。

对于使用 file_fdw 的外部表,EXPLAIN 会显示要读取的文件名或要运行的程序。对于文件,除非指定了 COSTS OFF,否则文件大小(以字节为单位)也会显示。

示例 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' );

就是这样 — 现在您可以直接查询您的日志了。当然,在生产环境中,您需要定义某种方式来处理日志轮转。


示例 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' );