COPY
在文件和表之间复制数据
| STDOUT} |
COPY table [(column [, ...])] FROM {'file' | |
STDIN} |
[[WITH] [OIDS] [HEADER] [DELIMITER [ AS ] 'delimiter'] [NULL [AS ] 'null string'] [ESCAPE [ AS ] 'escape' | 'OFF'] [NEWLINE [AS ] 'LF' | 'CR' | 'CRLF'] [CSV [QUOTE [ AS ] 'quote'] [FORCE NOT NULL column [, ...]] |
[FILL MISSING FIELDS] [[LOG ERRORS [INTO error_table] [KEEP] SEGMENT REJECT LIMIT cou^t [ROWS | PERCENT]] |
COPY {table [(column [, |
...])]| (query)} TO {'file |
[ [WITH] [OIDS] [HEADER] [DELIMITER [ AS ] 'delimiter'] [NULL [AS ] 'null string'] [ESCAPE [ AS ] 'escape' | 'OFF'] [CSV [QUOTE [AS ] 'quote'] [FORCE QUOTE column [,...]]] [IGNORE EXTERNAL PARTITIONS ] |
概要
描述
COPY在Greenplum的数据库表和标准文件系统文件之间移动数据。 COPY TO命令会拷贝的表的内容到一个文件,而COPY FROM会将数据从文件拷贝到表(不论表中数据是否存在,都会将数据追加到表中)。 COPY TO还可以复制一个SELECT查询的结果。
在COPY命令中附带一个文件名,就会使得GPDB的master节点直接从这个文件读写数据。这个文件必须在master节点上并且必须是从master节点的角度能看的到。如果带有STDIN 或 STDOUT,则数据会在客户端和master之间进行传输。
如果使用了段的拒绝极限(SEGMENT REJECTLIMIT),则COPY FROM操作就会在单行错误隔离的模式下运行。在这种场景下,单行的错误隔离只能应用在输入文件的行的格式错误上,例如,一个错误的数据类型,或无效的客户端编码序列的属性。约束错误,如违反NOT NULL,检查或唯一约束只能用于“要么全成功要么全失败”的输入模式进行处理。用户可以指定可以接受的错误行数(针对每个段),如果错误行数超过给定的值,则之后从操作整个副本将被中止,没有行会被加载。需要注意的是错误的行数是指每个段上的,而不是所有的加载。如果每个段拒绝限制没有达到,那么不包含错误的所有行会被加载。如果没有达到极限,所有正常的记录都会被加载,错误的数据都被丢弃。如果你想保存错误行进一步检查,可以使用错误日志INTO子句声明可选的错误表。含有格式错误的任何行然后将记录到指定的错误表。
Outputs
成功完成后,COPY命令返回表单的命令标签,其中count是复制的行数:
COPY COUNT。
如果在单行错误隔离模式下运行COPY FROM命令,
如果在单行错误隔离模式下运行COPY FROM命令,如果由于格式错误而未加载任何行,则将返回以下通知消息,其中count是拒绝的行数:
NOTICE: Rejected count badly formatted rows.
parameter
table
现存的文件名(可以包含schema前缀).
column
要复制的列的可选列表。 如果未指定列列表,则将复制表的所有列。
query
要复制其结果的SELECT或VALUES命令。 请注意,查询需要括号。
file
输入或输出文件的绝对路径名。
STDIN
指定输入来自客户端应用程序。
STDOUT
指定输出到客户端应用程序。
OIDS
指定复制每行的OID。 (如果为没有OID的表指定了OIDS,或者在复制查询的情况下,则会引发错误。)
delimiter
单个ASCII字符,用于分隔文件每行(行)中的列。默认值为文本模式下的制表符,CSV格式为逗号。
null string
表示空值的字符串。文本模式中的默认值为\ N(反斜杠-N),CSV模式中不含引号的空值。在不想将空值与空字符串区分开的情况下,即使在文本模式下,也可能更喜欢空字符串。当使用COPY FROM时,与此字符串匹配的任何数据项将被存储为空值,因此您应该确保使用与COPY TO中使用的字符串相同的字符串。
escape
指定用于C转义序列的单个字符(例如\ n,\ t,\ 100等等)以及引用可能被视为行或列分隔符的数据字符。确保选择在实际列数据中的任何地方都不使用的转义字符。默认转义字符是文本文件的\(反斜杠)或CSV文件的“(双引号)”,但是可以指定任何其他字符来表示转义,也可以通过指定文本格式的文件来禁用转义值“OFF1”作为转义值,对于具有许多不希望转义的嵌入式反斜杠的Web日志数据等数据非常有用。
NEWLINE
指定数据文件中使用的换行符 - LF(换行,0x0A),CR(回车,0x0D)或CRLF(回车加换行,0x0D 0x0A)。如果没有指定,一个Greenplum数据库段将通过查看其接收到的第一行数据并使用遇到的第一个换行符来检测换行类型。
CSV
选择逗号分隔值(CSV)模式。
HEADER
指定一个文件包含一个标题行和文件中每列的名称。在输出时,第一行包含表中的列名,在输入时,第一行将被忽略。
quote
以CSV模式指定报价字符。默认是双引号。
FORCE QUOTE
在CSV COPY TO模式下,强制引用用于每个指定列中的所有非NULL值。 NULL输出从不加引号。In csv copy to mode, forcesquoting to be used for all non-NULL values in each specified column. null output is neverquoted.
FORCE NOT NULL
在CSV COPY FROM模式下,处理每个指定的列,就像它被引用一样,因此不是NULL值。对于CSV模式中的默认空字符串(两个分隔符之间不存在),这将导致将缺少的值作为零长度字符串计算。
FILL MISSING FIELDS
在TEXT和CSV中的COPY FROM中,指定FILL MISSING FIELDS时,当一行数据在行或行的末尾缺少数据字段时,将丢失尾字段值设置为NULL(而不是报告错误)。空行,具有NOT NULL约束的字段和行上的尾随分隔符仍然会报告错误。
LOG ERRORS [INTO error_table] [KEEP]
日志错误[INTO error_table] [KEEP]
这是一个可选的子句,可以在SEGMENTREJECT LIMIT子句之前记录有关具有格式错误的行的信息。 INTO error_table子句指定在单行错误隔离模式下运行时会记录带格式错误的行的错误表。
如果未指定INTOerror_table子句,则内部存储错误日志信息(不在错误表中)。内部存储的错误日志信息可以使用GreenplumDatabase内置的SQL函数gp_read_error_log()进行访问。
如果指定的error_table已经存在,则使用它。如果不存在,则创建它。如果error_table存在且没有随机分布(创建表时未指定DISTRIBUTEDRANDOMLY子句),则返回错误。
如果命令生成错误表,并且没有产生错误,则默认值是在操作完成后删除错误表,除非指定了KEEP。如果创建表并且超出了错误限制,则整个事务将回滚,并且不会保存错误数据。如果您希望在这种情况下持续存在错误表,请在运行COPY之前创建错误表。
有关错误日志信息和内置函数的信息,请参阅注释,以查看和管理错误日志信息。
注意:可选的INTO error_table子句已被弃用,将来版本将不受支持。仅支持内部错误日志。
SEGMENT REJECT LIMIT count [ROWS |PERCENT]
在单行错误隔离模式下运行COPY FROM操作。如果输入行具有格式错误,则它们将被丢弃,前提是在加载操作期间在任何Greenplum数据库段实例上未达到拒绝限制计数。拒绝限制计数可以指定为行数(默认值)或总行数百分比(1-100)。如果使用PERCENT,则只有在处理了参数gp_reject_percent_threshold指定的行数之后,每个段才开始计算坏行百分比。gp_reject_percent_threshold的默认值为300行。诸如违反NOT NULL,CHECK或UNIQUE约束的约束错误仍将以“all-or-nothing”输入模式进行处理。
如果错误约束没有达到,则正常记录都被加载,错误记录都被丢弃。
注意:如果首先未触发SEGMENT REJECT LIMIT或未指定,则Greenplum数据库会限制可能包含格式错误的初始行数。如果前1000行被拒绝,则COPY操作将被停止并回滚。
可以使用Greenplum数据库服务器配置参数gp_initial_bad_row_limit更改初始拒绝行的数量限制。有关参数的信息,请参阅服务器配置参数。
IGNOREEXTERNAL PARTITIONS
从分区表复制数据时,数据不会从作为外部表的叶子分区复制。当不复制数据时,会将消息添加到日志文件中。
如果未指定此子句,并且Greenplum数据库尝试从作为外部表的叶子分区复制数据,则会返回错误。
有关指定从作为外部表的叶子分区复制数据的SQL查询的信息,请参阅下一节“注释”。
Notes
COPY只能与表一起使用,而不能与外部表或视图一起使用。但是,您可以写COPY
(SELECT* FROM viewname)TO ...
要从具有作为外部表的叶子分区的分区表复制数据,请使用SQL查询来复制数据。例如,如果表my_sales包含一个具有作为外部表的叶子子分区,则此命令COPYmy_sales TO stdout返回错误。此命令将数据发送到stdout:
COPY(SELECT* from my_sales)TO stdout
BINARY关键字将所有数据存储/读取为二进制格式而不是文本。它比正常的文本模式要快一点,但二进制格式的文件在机器架构和Greenplum数据库版本之间的移植性更低。另外,如果数据是二进制格式,则不能以单行错误隔离模式运行COPYFROM。
您必须对其值由COPYTO读取的表具有SELECT权限,并在COPY FROM插入的值上插入特权。
在COPY命令中命名的文件由数据库服务器直接读取或写入,而不是由客户端应用程序读取或写入。因此,它们必须驻留在Greenplum数据库主机主机上或可访问,而不是客户端。它们必须由Greenplum数据库系统用户(服务器运行的用户ID)而不是客户机可访问和可读写。COPY命名文件只允许数据库超级用户使用,因为它允许读取或写入服务器具有访问权限的任何文件。
COPYFROM将调用目标表上的任何触发器和检查约束。但是,它不会调用重写规则。请注意,在此版本中,不对单行错误隔离模式评估对约束的违规。
COPY输入和输出受Datestyle影响。为了确保可以使用可能使用非默认Datestyle设置的其他Greenplum数据库安装,Datestyle应在使用前设置为ISO
复制到。
默认情况下,COPY在第一个错误时停止运行。在COPYTO的情况下,这不应该导致问题,但目标表已经在COPY FROM中已经接收到较早的行。这些行将不可见或可访问,但它们仍占用磁盘空间。如果故障发生在大的COPYFROM操作中,这可能会相当大量的浪费磁盘空间。您可能希望调用VACUUM来恢复浪费的空间。另一个选择是使用单行错误隔离模式来过滤错误行,同时仍然加载好的行。
当您将LOGERRORS IN指定为error_table时,Greenplum Database会创建表error_table,其中包含读取外部表时发生的错误。表定义如下:
CREATETABLE error_table_name(cmdtime timestamptz,relname text,filename text,linenumint,bytenum int,errmsg text,rawdata text,rawbytes bytea) DISTRIBUTED RANDOMLY;
您可以使用SQL命令查看表中的信息。
对于未指定INTOerror_tabie时内部存储的错误日志数据:
•使用内置的SQL函数gp_read_error_log('table_name')。它需要对table_name具有SELECT权限。此示例显示使用COPY命令加载到表ext_expenses中的数据的错误日志信息:
select* from gp_read_error_log(,ext_expenses,);
错误日志包含与错误表相同的列。
如果table_name不存在,该函数返回FALSE。
•如果指定的表存在错误日志数据,则新的错误日志数据将附加到现有的错误日志数据。错误日志信息不会复制到镜像段。
•使用内置的SQL函数gp_truncate_error_iog('tabie_name')删除table_name的错误日志数据。它需要表所有者权限此示例删除将数据移动到表ext_expenses时捕获的错误日志信息:
SELECTgp_truncate_error_log(,ext_expenses,);
如果table_name不存在,该函数返回FALSE。
指定*通配符以删除当前数据库中现有表的错误日志信息。指定字符串*。*以删除所有数据库错误日志信息,包括由于以前的数据库问题而未被删除的错误日志信息。如果指定*,则需要数据库所有者权限。如果指定了*。*,则需要操作系统超级用户权限。
当不是超级用户的Greenplum数据库用户运行COPY命令时,该命令可以由资源队列控制。必须使用ACTIVE_STATEMENTS参数配置资源队列,该参数指定分配给该队列的角色可执行的查询数量的最大限制。Greenplum数据库不将成本值或内存值应用于COPY命令,只有成本或内存限制的资源队列不影响COPY命令的运行。
非超级用户可以运行可以运行这些类型的COPY命令:
•来源为stdin的COPY FROM命令
•COPY TO命令目的地是stdout
有关资源队列的信息,请参阅“Greenplum数据库管理员指南”中的“具有资源队列的工作负载管理”。
File Formats
COPY支持的文件格式。
Text Format
当使用没有BINARY或CSV选项的COPY时,读取或写入的数据是每个表行一行的文本文件。一行中的列由分隔符字符(默认选项卡)分隔。列值本身是由每个属性的数据类型的输出函数生成的或输入函数可接受的字符串。使用指定的空字符串代替为空的列。如果输入文件的任何行包含比预期的列更多或更少的列,则COPY FROM将引发错误。如果指定OIDS,OID将被读取或写入第一列,位于用户数据列之前。
数据文件有两个对COPY有特殊含义的保留字符:
•指定的分隔符(默认为tab),用于分隔数据文件中的字段。
•UNIX样式换行符(\n或oxoa),用于指定数据文件中的新行。强烈建议生成COPY数据的应用程序将数据行Feed转换为UNIX样式的换行符,而不是MicrosoftWindows样式的回车换行(\r\n或oxoa oxod)。
如果您的数据包含这些字符,您必须转义该字符,因此COPY将其视为数据而不是字段分隔符或新行。
默认情况下,转义字符是文本格式文件的\(反斜杠)和csv格式文件的“(双引号)”。如果要使用其他转义字符,可以使用ESCAPE AS子句。确保选择一个在数据文件中的任何地方不被用作实际数据值的转义字符,也可以使用ESCAPE'OFF'禁止文本格式文件中的转义。
例如,假设您有一个具有三列的表,并且您想使用COPY加载以下三个字段。
•百分比符号=%
•垂直条= |
•反斜杠= \
您的指定的分隔符是| (管道字符),您指定的转义字符是*(星号)。数据文件中格式化的行将如下所示:
percentagesign = % 丨 vertical bar = *| 丨 backslash = \
请注意,使用星号(*)转义数据的一部分的管道字符。还要注意,由于我们使用替代转义字符,我们不需要转义反斜杠。
以下字符必须在转义字符前面,如果它们显示为列值的一部分:转义字符本身,换行符,回车符和当前分隔符字符。您可以使用ESCAPE AS子句指定其他转义字符。
CSV Format
此格式用于导入和导出许多其他程序(如电子表格)使用的逗号分隔值(CSV)文件格式。而不是GreenplumDatabase标准文本模式使用的转义,它会生成并识别常用的CSV转义机制。
每个记录中的值由DELIMITER字符分隔。如果值包含分隔符字符,则QUOTE字符,ESCAPE字符(默认为双引号),NULL字符串,回车符或换行字符,则整个值前缀为QUOTE字符。在特定列中输出非NULL值时,也可以使用FORCE QUOTE强制引用。
CSV格式没有标准的方法来区分NULL值和空字符串。 Greenplum数据库COPY通过引用来处理这个。 NULL作为NULL字符串输出,不引用,而与NULL字符串匹配的数据值被引用。因此,使用默认设置,NULL将被写为无引号的空字符串,而空字符串用双引号(“”)写入。阅读值遵循相似的规则。您可以使用FORCE NOTNULL来阻止特定列的NULL输入比较。
因为反斜杠不是CSV格式的特殊字符,\。,数据结尾标记也可以显示为数据值。为了避免任何误解,一个\。出现在行上的单个条目的数据值在输出上自动引用,并且在输入时(如果引用)不会被解释为数据结尾标记。如果您正在加载由另一个应用程序创建的文件,该文件具有单个未引用的列,并且值可能为\。,则可能需要在输入文件中引用该值。
注意:在CSV模式下,所有字符都很重要。由空格或DELIMITER以外的任何字符包围的引用值将包含这些字符。如果您从系统中将数据从白色空间填充到某些固定宽度的系统中,则可能会导致错误。如果出现这种情况,则在将数据导入到Greenplum数据库之前,您可能需要预处理CSV文件以删除尾随的空格。
Binary Format
BINARY格式由文件头,包含行数据的零个或多个元组和文件预告片组成。
标题和数据是网络字节顺序。
• File Header —文件头由15个字节的固定字段组成,后面是可变长度的标题扩展区。固定字段是:
• Signature —11字节序列PGCOPY \ n \377 \ r \ n \ 0 - 请注意,零字节是签名的必需部分。 (签名被设计为容易地识别由非8位清理传输所掩盖的文件,该签名将通过行尾转换过滤器,丢弃的零字节,丢弃的高位或奇偶变化。)
• Flags field—32位整数位掩码,用于表示文件格式的重要方面。位从0(LSB)到31(MSB)编号。请注意,此字段以网络字节顺序(最高有效字节优先)存储,以及文件格式中使用的所有整数字段。位16-31保留以表示关键文件格式问题;如果发现在此范围内设置了意外的位,读取器将中止。 bit 0-15被保留以表示向后兼容的格式问题;读者应该简单地忽略在此范围内设置的任何意外的位。目前只定义了一个标志,其余的标志位必须为零(如果数据有OID,则为16:1,否则为0)。
• Header extension area length —32位整数,标题剩余字节长度(不包括自身)。目前,这是零,第一个元组立即跟随。格式的未来更改可能允许在标题中存在附加数据。读者应该默默地跳过任何不知道该怎么做的标题扩展名数据。标题扩展区域被设想为包含一系列自识别块。标志字段不是要告诉读者扩展区域是什么。标题扩展内容的具体设计留待以后发布。
Tuples —每个元组以元组中的字段数的16位整数计数开始。(目前,表中的所有元组都将具有相同的计数,但可能并不总是如此)。然后,对于元组中的每个字段重复,都有一个32位长度的字,后跟多个字段的字段数据。 (长度字不包括本身,可以为零)。作为特殊情况,-1表示NULL字段值。在NULL的情况下没有值字节。
字段之间没有对齐填充或任何其他额外的数据。
目前,COPY BINARY文件中的所有数据值都被假定为二进制格式(格式代码一)。预计未来的扩展可能会添加一个头域,允许指定每列格式代码。
如果OID包含在文件中,则OID字段紧跟在字段计数字之后。这是一个正常的字段,除了它不包括在字段计数中。特别是它有一个长度字- 这将允许处理4字节与8字节OID没有太多的痛苦,并将允许OID显示为null,如果有证明是可取的。
• File Trailer —文件预告片由包含-1的16位整数字组成。这很容易与元组的字段计数字区分开。如果字段计数字不是-1也不是预期的列数,读者应该报告错误。这提供额外的检查,以防止与数据不同步。
示例
Copy a tableto the client using the vertical bar (|) as the field delimiter:
COPY countryTO STDOUT WITH DELIMITER '|';
Copy data froma file into the country table:
COPY countryFROM ,/home/usr1/sql/country_data,;
Copy into afile just the countries whose names start with 'A':
COPY (SELECT *FROM country WHERE country_name LIKE 'A%') TO'/home/usr1/sql/a_list_countries.copy';
Create anerror table called err_sales to use with single row error isolation mode:
CREATE TABLE err_sales ( cmdtimetimestamptz, relname text,
filename text,linenum int, bytenum int, errmsg text, rawdata text, rawbytes bytea )DISTRIBUTED RANDOMLY;
Copy data froma file into the sales table using single row error isolation mode:
COPY salesFROM '/home/usr1/sql/sales_data' LOG ERRORS INTO err_sales SEGMENT REJECT LIMIT10 ROWS;
兼容性
There is no copy statement in theSQL standard.
相关参考
CREATE EXTERNAL TABLE