PG中的SQL copy和元命令copy命令

0    2021    9

Tags:

👉 本文共约11695个字,系统预计阅读时间或需44分钟。

COPY和“\copy”的区别

psql支持文件数据导入到数据库,也支持数据库表数据导出到文件中。 COPY命令和\copy 命令都支持这两类操作,但两者有如下区别:

  • COPY 命令是SQL命令,\copy 命令是元命令。
  • 执行COPY 命令的用户必须具有SUPERUSER超级权限(将数据通过stdin/stdout方式导入导出情况除外)或授予了默认角色pg_read_server_filespg_write_server_filespg_execute_server_program之一的用户,而 \copy 元命令不需要SUPERUSER权限。
  • COPY 命令读取或写入数据库服务端主机上的文件,而 \copy 元命令是从psql客户端主机读取或写入文件。
  • 从性能方面看, 大数据量导出文件或大文件数据导入数据库,COPY 比 \copy 性能高。

COPY命令

COPY — 在一个文件和一个表之间复制数据

大纲

描述

COPY在 PostgreSQL表和标准文件系统文件之间 移动数据。COPY TO把一个表的内容复制 一个文件,而COPY FROM一个文件复制数据到一个表(把数据追加到表中原有数 据)。COPY TO也能复制一个 SELECT查询的结果。

如果指定了一个列列表,COPY TO将只把指定列的数据复制到文件。对于COPY FROM,文件中的每个字段将按顺序插入到指定列中。COPY FROM命令的列列表中没有指定的表列则会采纳其默认值。

带一个文件名的COPY指示 PostgreSQL服务器直接从一个文件读取 或者写入到一个文件。该文件必须是 PostgreSQL用户(运行服务器的用户 ID) 可访问的并且应该以服务器的视角来指定其名称。当指定了 PROGRAM时,服务器执行给定的命令并且从该程序的标准 输出读取或者写入到该程序的标准输入。该程序必须以服务器的视角指定,并且 必须是PostgreSQL用户可执行的。在指定 STDIN或者STDOUT时,数据会通过客 户端和服务器之间的连接传输。

参数

  • table_name

    一个现有表的名称(可以是模式限定的)。

  • column_name

    可选的要被复制的列列表。如果没有指定列列表,则该表的所有列除了生成的列都会被复制。

  • query

    其结果要被复制的SELECTVALUESINSERTUPDATE或者 DELETE命令。注意查询周围的圆括号是必要的。对于INSERTUPDATE以及 DELETE查询,必须提供一个 RETURNING 子句并且 目标关系不能具有会扩展成多条语句的条件规则、 ALSO规则或者INSTEAD规则。

  • filename

    输入或者输出文件的路径名。一个输入文件的名称可以是一个绝对或相对路径, 但一个输出文件的名称必须是绝对路径。Windows 用户可能需要使用一个 E''字符串并且双写路径名称中使用的任何反斜线。

  • PROGRAM

    一个要执行的命令。在COPY FROM中,输入 将从该命令的标准输出读取,而在COPY TO中,输出会 写入到该命令的标准输入。注意该命令是由 shell 调用,因此如果你需要传递任何来自不可信来源的 参数给 shell 命令,你必须小心地剥离那些可能对 shell 有特殊意义的特殊 字符。出于安全原因,最好使用一个固定的命令字符串,或者至少避免传递 任何用户输入到其中。

  • STDIN

    指定输入来自客户端应用。

  • STDOUT

    指定输出会去到客户端应用。

  • boolean

    指定选中的选项是应该被关闭还是打开。可以写TRUEON1来启用选项,写 FALSEOFF0禁用它。 boolean值也可以被省略, 那样会假定为TRUE

  • FORMAT

    选择要读取或者写入的数据格式: textcsv(逗号分隔值)或者binary。 默认是text

  • FREEZE

    请求复制已经完成了行冻结的数据,就好像在运行 VACUUM FREEZE命令之后复制。这是为了初始 数据载入的性能而设计的。只有被载入表已经在当前子事务中被创建 或截断、该事务中没有游标打开并且该事务没有持有更旧的快照时, 行才会被冻结。目前无法在分区表上执行COPY FREEZE。注意一旦成功地载入,所有其他会话将能立即看到该数据。这违背了 普通的 MVCC 可见性规则,指定该选项的用户应该注意这可能会导致 的潜在问题。

  • DELIMITER

    指定分隔文件每行中各列的字符。文本格式中默认是一个制表符, 而CSV格式中默认是一个逗号。这必须是一个单一 的单字节字符。使用binary格式时不允许这个选项。

  • NULL

    指定表示一个空值的字符串。文本格式中默认是 \N(反斜线-N),CSV格式中默认 是一个未加引用的空串。在你不想区分空值和空串的情况下,即使在文本 格式中你也可能更喜欢空串。使用binary格式时不允许这 个选项。注意在使用COPY FROM时,任何匹配 这个串的数据项将被存储为空值,因此你应该确定你使用的是和 COPY TO时相同的串。

  • HEADER

    指定文件包含标题行,其中有每一列的名称。在输出时,第一行包含 来自表的列名。在输入时,第一行会被忽略。只有使用 CSV格式时才允许这个选项。

  • QUOTE

    指定一个数据值被引用时使用的引用字符。默认是双引号。 这必须是一个单一的单字节字符。只有使用 CSV格式时才允许这个选项。

  • ESCAPE

    指定应该出现在一个匹配QUOTE值的数据字符之前 的字符。默认和QUOTE值一样(这样如果引用字符 出现在数据中,它会被双写)。这必须是一个单一的单字节字符。 只有使用CSV格式时才允许这个选项。

  • FORCE_QUOTE

    强制必须对每个指定列中的所有非NULL值使用引用。 NULL输出不会被引用。如果指定了*, 所有列的非NULL值都将被引用。只有在 COPY TO中使用CSV格式时才允许 这个选项。

  • FORCE_NOT_NULL

    不要把指定列的值与空值串匹配。在空值串就是空串的默认情况下, 这意味着空串将被读作长度为零的字符串而不是空值(即使它们没有 被引用)。只有在COPY FROM中使用 CSV格式时才允许这个选项。

  • FORCE_NULL

    将指定列的值与空值串匹配(即使它已经被加上引号),并且在找到 匹配时将该值设置为NULL。在空值串就是空串的默认 情况下,这会把一个被引用的空串转换为 NULL。 只有在COPY FROM中使用 CSV格式时才允许这个选项。

  • ENCODING

    指定文件被以encoding_name编码。如果省略 这个选项,将使用当前的客户端编码。详见下文的注解。

  • WHERE

    WHERE子句是可选的,其一般形式是:WHERE *condition* 其中condition是计算结果为boolean类型的任意表达式。任何不满足此条件的行都不会插入到表中。在用实际的行值替换任何变量引用时,如果该行返回true,则该行满足条件。目前,在WHERE表达式中不允许使用子查询,并且值的计算不会看到COPY本身所做的任何更改(当表达式包含对VOLATILE函数的调用时,这一点很重要)。

输出

在成功完成时,一个COPY命令会返回一个形为

的命令标签。 count是被复制 的行数。

注意

如果命令不是COPY ... TO STDOUT或者等效的 psql元命令\copy ... to stdout, psql将只打印这个命令标签。这是为了防止弄混 命令标签和刚刚打印的数据。

注解

COPY TO只能被用于纯粹的表,不能用于视图。 不过你可以写COPY (SELECT * FROM *viewname*) TO ...来拷贝一个视图的当前内容。

COPY FROM可以被用于普通表、外部表、分区表或者具有INSTEAD OF INSERT触发器的视图。

COPY只处理提到的表,它不会从子表复制 数据或者复制数据到子表中。例如 COPY *table* TO 会显示与SELECT * FROM ONLY *table*相同的数据。而COPY (SELECT * FROM *table*) TO ... 可以被用来转储一个继承层次中的所有数据。

你必须拥有被COPY TO读取的表上的选择特权, 以及被COPY FROM插入的表上的插入特权。 拥有在命令中列出的列上的特权就足够了。

如果对表启用了行级安全性,相关的SELECT策略将应用于COPY *table* TO语句。当前,有行级安全性的表不支持COPY FROM。不过可以使用等效的INSERT语句。

COPY命令中提到的文件会被服务器(而不是 客户端应用)直接读取或写入。因此它们必须位于数据库服务器(不是客户 端)的机器上或者是数据库服务器可以访问的。它们必须是 PostgreSQL用户(运行服务器的用户 ID)可访问的并且是可读或者可写的。类似地,用PROGRAM 指定的命令也会由服务器(不是客户端应用)直接执行,它也必须是 PostgreSQL用户可以执行的。 只允许数据库超级用户或者授予了默认角色pg_read_server_filespg_write_server_filespg_execute_server_program之一的用户COPY一个文件或者命令, 因为它允许读取或者写入服务器有特权访问的任何文件或者运行服务器有特权访问的程序。

不要把COPY和 psql指令 \copy 弄混。\copy会调用 COPY FROM STDIN或者COPY TO STDOUT,然后读取/存储一个 psql客户端可访问的文件中的数据。 因此,在使用\copy时,文件的可访 问性和访问权利取决于客户端而不是服务器。

我们推荐在COPY中使用的文件名总是 指定为一个绝对路径。在COPY TO的 情况下服务器会强制这一点,但是对于 COPY FROM你可以选择从一个用相对 路径指定的文件中读取。该路径将根据服务器进程(而不是客户端) 的工作目录(通常是集簇的数据目录)解释。

PROGRAM执行一个命令可能会受到操作系统 的访问控制机制(如 SELinux)的限制。

COPY FROM将调用目标表上的任何触发器 和检查约束。但是它不会调用规则。

对于标识列,COPY FROM命令将总是写上输入数据中提供的列值,这和INSERT的选项OVERRIDING SYSTEM VALUE的行为一样。

COPY输入和输出受到 DateStyle的影响。为了确保到其他 可能使用非默认DateStyle设置的 PostgreSQL安装的可移植性,在使用 COPY TO前应该把 DateStyle设置为ISO。避免转储把 IntervalStyle设置为 sql_standard的数据也是一个好主意,因为负的区间值可能会 被具有不同IntervalStyle设置的服务器解释错误。

即使数据会被服务器直接从一个文件读取或者写入一个文件而不通过 客户端,输入数据也会被根据ENCODING选项或者当前 客户端编码解释,并且输出数据会被根据ENCODING或 者当前客户端编码进行编码。

COPY会在第一个错误处停止操作。这在 COPY TO的情况下不会导致问题,但是 在COPY FROM中目标表将已经收到了一 些行。这些行将不会变得可见或者可访问,但是它们仍然占据磁盘空间。 如果在一次大型的复制操作中出现错误,这可能浪费相当可观的磁盘空间。 你可能希望调用VACUUM来恢复被浪费的 空间。

FORCE_NULLFORCE_NOT_NULL可以被同时 用在同一列上。这会导致把已被引用的空值串转换为空值并且把未引用的空值 串转换为空串。

文件格式

文本格式

在使用text格式时,读取或写入的是一个文本文件, 其中每一行就是表中的一行。一行中的列被定界字符分隔。列值 本身是由输出函数产生的或者是可被输入函数接受的属于每个属性 数据类型的字符串。在为空值的列的位置使用指定的空值串。如果 输入文件的任何行包含比预期更多或者更少的列, COPY FROM将会抛出一个错误。

数据的结束可以表示为一个只包含反斜线-点号(\.)的 单一行。从一个文件读取时,数据结束标记并不是必要的,因为文件 结束符就已经足够用了。只有使用 3.0 客户端协议之前的客户端应用 复制数据时才需要它。

反斜线字符(\)可以被用在 COPY数据中来引用被用作行或者列定界符的 字符。特别地,如果下列字符作为一个列值的一部分出现,它们 必须\被前置一个反斜线:反斜线本身、新行、回车以及 当前的定界符字符。

COPY TO会不加任何反斜线返回指定的空值串。 相反,COPY FROM会在移除反斜线之前把输入 与空值串相匹配。因此,一个空值串(例如\N)不会与实 际的数据值\N(它会被表示为\\N)搞混。

COPY FROM识别下列特殊的反斜线序列:

序列表示
\b退格 (ASCII 8)
\f换页 (ASCII 12)
\n新行 (ASCII 10)
\r回车 (ASCII 13)
\t制表 (ASCII 9)
\v纵向制表 (ASCII 11)
\digits反斜线后跟一到三个十进制位表示该数字代码对应的字符
\xdigits反斜线加x后跟一到三个十六进制位表示该数字代码对应的字符

当前,COPY TO不会发出一个十进制或十六进制位 反斜线序列,但是它确实把上面列出的其他序列用于那些控制字符。

任何上述表格中没有提到的其他反斜线字符将被当作表示其本身。不过,要注意 增加不必要的反斜线,因为那可能意外地产生一个匹配数据结束标记( \.)或者空值串(默认是\N)的字符串。这些字符串 将在完成任何其他反斜线处理之前被识别。

强烈建议产生COPY数据的应用把数据新行和回车分别 转换为\n\r序列。当前可以把一个数据回车表示为 一个反斜线和回车,把一个数据新行表示为一个反斜线和新行。不过,未来的发行 可能不会接受这些表示。如果在不同的机器之间(例如从 Unix 到 Windows) 传输COPY文件,它们也很容易受到破坏。

COPY TO将用一个 Unix 风格的新行( “\n”)终止每一行。运行在 Microsoft Windows 上的服务器则会输出回车/新行(“\r\n”),不过只对 COPY到一个服务器文件这样做。为了做到跨平台一致, COPY TO STDOUT总是发送“\n”而 不管服务器平台是什么。COPY FROM能够处理以 新行、回车或者回车/新行结尾的行。为了减少由作为数据的未加反斜线的新行 或者回车带来的风险,如果输出中的行结束并不完全相似, COPY FROM将会抱怨。

CSV 格式

这种格式选项被用于导入和导出很多其他程序(例如电子表格)使用的逗号 分隔值(CSV)文件格式。不同于 PostgreSQL标准文本格式使用的转义 规则,它产生并且识别一般的 CSV 转义机制。

每个记录中的值用DELIMITER字符分隔。如果值包含 定界符字符、QUOTE字符、NULL字符串、 一个回车或者换行字符,那么整个值会被加上QUOTE字符 作为前缀或者后缀,并且在该值内QUOTE字符或者 ESCAPE字符的任何一次出现之前放上转义字符。在输出 指定列中非NULL值时,还可以使用 FORCE_QUOTE来强制加上引用。

本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信dbaup66,谢谢!
AiDBA后续精彩内容已被站长无情隐藏,请输入验证码解锁本文!
验证码:
获取验证码: 请先关注本站微信公众号,然后回复“验证码”,获取验证码。在微信里搜索“AiDBA”或者“dbaup6”或者微信扫描右侧二维码都可以关注本站微信公众号。

标签:

Avatar photo

小麦苗

学习或考证,均可联系麦老师,请加微信db_bao或QQ646634621

您可能还喜欢...

发表回复