加载 CSV 数据
使用 fcsvparser
加载 CSV 格式(逗号分隔值)的数据。由于不存在正式的 CSV 标准,Vertica 支持 RFC 4180 标准为 fcsvparser
的默认行为。其他解析器参数则将 CSV 选项的各种组合简化成列式表或 Flex 表。使用 fcsvparser
解析以下 CSV 数据格式:
-
**RFC 4180:**Vertica Flex 表的 RFC4180 CSV 格式解析器。此格式的参数为固定值,无法更改。
-
传统: 传统 CSV 解析器允许您指定参数值,如分隔符或记录终止符。有关参数的详细列表,请参阅 FCSVPARSER。
使用默认解析器设置
这些固定的参数设置适用于 RCF4180 格式。
您可以对 enclosed_by
和 escape
使用相同的值。其他值必须唯一。
使用 type
参数指示文件符合 RFC 4180 格式还是传统格式。您可以将 type
指定为 RCF4180
。但您必须首先验证数据是否与前面 RFC4180 格式参数的固定值兼容。type
参数的默认值为 RFC4180.
加载 CSV 数据 (RFC4180)
请按照以下步骤,使用 fcsvparser
加载 RFC4180 CSV 数据格式的数据。
要执行此任务,假定待加载的 CSV 文件具有以下示例内容:
$ more /home/dbadmin/flex/flexData1.csv
sno,name,age,gender
1,John,14,male
2,Mary,23,female
3,Mark,35,male
-
创建 Flex 表:
=> CREATE FLEX TABLE csv_basic(); CREATE TABLE
-
使用
fcsvparser
从 CSV 文件加载数据:=> COPY csv_basic FROM '/home/dbadmin/flex/flexData1.csv' PARSER fcsvparser(); Rows Loaded ------------- 3 (1 row)
-
查看加载到 Flex 表中的数据:
=> SELECT maptostring(__raw__) FROM csv_basic; maptostring ---------------------------------------------------------------------------------- { "age" : "14", "gender" : "male", "name" : "John", "sno" : "1" } { "age" : "23", "gender" : "female", "name" : "Mary", "sno" : "2" } { "age" : "35", "gender" : "male", "name" : "Mark", "sno" : "3" } (3 rows)
加载 CSV 数据(传统)
请按照以下步骤,使用 fcsvparser
加载传统 CSV 数据格式的数据。
在此示例中,CSV 文件将 $
用作 delimiter
,将 #
用作 record_terminator
。待加载的示例 CSV 文件具有以下内容:
$ more /home/dbadmin/flex/flexData1.csv
sno$name$age$gender#
1$John$14$male#
2$Mary$23$female#
3$Mark$35$male#
-
创建 Flex 表:
=> CREATE FLEX TABLE csv_basic(); CREATE TABLE
-
使用带有参数
type='traditional'
、delimiter='$'
和record_terminator='#'
的fscvparser
加载 Flex 表中的数据:=> COPY csv_basic FROM '/home/dbadmin/flex/flexData2.csv' PARSER fcsvparser(type='traditional', delimiter='$', record_terminator='#'); Rows Loaded ------------- 3 (1 row)
-
查看加载到 Flex 表中的数据:
=> SELECT maptostring(__raw__) FROM csv_basic; maptostring ---------------------------------------------------------------------------------- { "age" : "14", "gender" : "male", "name" : "John", "sno" : "1" } { "age" : "23", "gender" : "female", "name" : "Mary", "sno" : "2" } { "age" : "35", "gender" : "male", "name" : "Mark", "sno" : "3" } (3 rows)
拒绝重复值
您可以通过使用 fcsvparser
的 reject_on_duplicate=true
选项拒绝重复值。加载在拒绝重复值后继续。下个示例演示了如何使用此参数,接着显示了指定的异常和拒绝的数据文件。将被拒绝的数据保存到表而不是文件中,包括数据及其异常。
=> CREATE FLEX TABLE csv_basic();
CREATE TABLE
=> COPY csv_basic FROM stdin PARSER fcsvparser(reject_on_duplicate=true)
exceptions '/home/dbadmin/load_errors/except.out' rejected data '/home/dbadmin/load_errors/reject.out';
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
>> A|A
>> 1|2
>> \.
=> \! cat /home/dbadmin/load_errors/reject.out
A|A
=> \! cat /home/dbadmin/load_errors/except.out
COPY: Input record 1 has been rejected (Processed a header row with duplicate keys with
reject_on_duplicate specified; rejecting.). Please see /home/dbadmin/load_errors/reject.out,
record 1 for the rejected record.
COPY: Loaded 0 rows, rejected 1 rows.
拒绝包含实体化列类型错误的数据
fcsvparser
解析器具有一个布尔参数 reject_on_materialized_type_error
。将此参数设置为 true
将导致行被拒绝,前提是输入数据中同时存在以下情况:
-
包括与现有实体化列匹配的键
-
具有无法强迫采用实体化列数据类型的键值
以下示例演示了如何设置该参数。
-
创建一个表
reject_true_false
,带有两个实际列:=> CREATE FLEX TABLE reject_true_false(one int, two int); CREATE TABLE
-
使用
fcsvparser
在reject_on_materialized_type_error=false
的情况下将 CSV 数据加载至表(从 STDIN 中)中。虽然false
是默认值,但您可以显式指定它,如下所示。此外,设置参数header=true
以指定输入值对应的列:=> COPY reject_true_false FROM stdin PARSER fcsvparser(reject_on_materialized_type_error=false,header=true); Enter data to be copied followed by a newline. End with a backslash and a period on a line by itself. >> one,two >> 1,2 >> "3","four" >> "five",6 >> 7,8 >> \.
-
调用
maptostring
在加载数据之后显示表值:=> SELECT maptostring(__raw__), one, two FROM reject_true_false; maptostring | one | two ----------------------------------------+-----+----- { "one" : "1", "two" : "2" } | 1 | 2 { "one" : "3", "two" : "four" } | 3 | { "one" : "five", "two" : "6" } | | 6 { "one" : "7", "two" : "8" } | 7 | 8 (4 rows)
-
截断该表以清空表中存储的数据:
=> TRUNCATE TABLE reject_true_false; TRUNCATE TABLE
-
重新加载相同的数据,但这次请设置
reject_on_materialized_type_error=true
:=> COPY reject_true_false FROM stdin PARSER fcsvparser(reject_on_materialized_type_error=true,header=true); Enter data to be copied followed by a newline. End with a backslash and a period on a line by itself. >> one,two >> 1,2 >> "3","four" >> "five",6 >> 7,8 >> \.
-
调用
maptostring
显示表内容。当前仅加载两行,而之前的结果中有四行。含有数据类型不正确的输入值的行已被拒绝:=> SELECT maptostring(__raw__), one, two FROM reject_true_false; maptostring | one | two -------------------------------------+-----+----- { "one" : "1", "two" : "2" } | 1 | 2 { "one" : "7", "two" : "8" } | 7 | 8 (2 rows)
注意
如果存在类型不匹配,解析器fcsvparser
将使用 null
值;而您将 reject_on_materialized_type_error
参数设置为 false
。
拒绝或忽略空行
有效的 CSV 文件可能包含空键值对。这些行对 SQL 无效。您可以使用两个布尔 FCSVPARSER
参数拒绝或忽略空行,从而控制其行为:
reject_on_empty_key
omit_empty_keys
下面的示例演示了如何设置这些参数:
-
创建 Flex 表:
=> CREATE FLEX TABLE csv_basic(); CREATE TABLE
-
使用
fcsvparser
在reject_on_empty_key=false
的情况下将 CSV 数据加载至表(从 STDIN 中)中。虽然false
是默认值,但您可以显式指定它,如下所示。此外,设置参数header=true
以指定输入值对应的列:=> COPY csv_basic FROM stdin PARSER fcsvparser(reject_on_empty_key=false,header=true); Enter data to be copied followed by a newline. End with a backslash and a period on a line by itself. >> ,num >> 1,2 >> \.
-
调用
maptostring
在加载数据之后显示表值:=>SELECT maptostring(__raw__) FROM csv_basic; maptostring ---------------------------------- { "" : "1", "num" : "2" } (1 row)
-
截断该表以清空表中存储的数据:
=> TRUNCATE TABLE csv_basic; TRUNCATE TABLE
-
重新加载相同的数据,但这次请设置
reject_on_empty_key=true
:=> COPY csv_basic FROM stdin PARSER fcsvparser(reject_on_empty_key=true,header=true); Enter data to be copied followed by a newline. End with a backslash and a period on a line by itself. >> ,num >> 1,2 >> \.
-
调用
maptostring
显示表内容。未加载任何行,因为其中一个键为空:=>SELECT maptostring(__raw__) FROM csv_basic; maptostring ------------- (0 rows)
-
截断该表以清空表中存储的数据:
=> TRUNCATE TABLE csv_basic; TRUNCATE TABLE
-
重新加载相同的数据,但这次请设置
omit_empty_keys=true
:=> COPY csv_basic FROM stdin PARSER fcsvparser(omit_empty_keys=true,header=true); Enter data to be copied followed by a newline. End with a backslash and a period on a line by itself. >> ,num >> 1,2 >> \.
-
调用
maptostring
显示表内容。现已加载一行,带空键的行已被忽略:=> SELECT maptostring(__raw__) FROM csv_basic; maptostring --------------------- { "num" : "2" } (1 row)
注意
如果不存在标题名称,则fcsvparser
使用默认标题
ucoln
,其中 n 是列偏移量。如果表的标题名称与键名相匹配,则解析器将为列加载匹配键的关联值。
使用 NULL 参数
使用带有 fcsvparser
的 COPY NULL
元数据参数,将 NULL 值加载到 Flex 表中。
下面的示例使用此参数:
-
创建 Flex 表:
=> CREATE FLEX TABLE fcsv(c1 int); CREATE TABLE
-
使用 STDIN 和 NULL 参数将 CSV 数据加载到 Flex 表中:
=> COPY fcsv FROM STDIN PARSER fcsvparser() NULL 'NULL' ; Enter data to be copied followed by a newline. End with a backslash and a period on a line by itself. >> a,b,c1 >> 10,20,NULL >> 20,30,50 >> 20,30,40 >> \.
-
使用
compute_flextable_keys_and_build_view
函数计算键并构建 Flex 视图:=> SELECT compute_flextable_keys_and_build_view('fcsv'); compute_flextable_keys_and_build_view -------------------------------------------------------------------------------- Please see public.fcsv_keys for updated keys The view public.fcsv_view is ready for querying (1 row)
-
查看 Flex 视图并替换 NULL 值:
=> SELECT * FROM public.fcsv_view; a | b | c1 ----+----+---- 20 | 30 | 50 10 | 20 | 20 | 30 | 40 (3 rows)
=> SELECT a,b, ISNULL(c1,-1) from public.fcsv_view; a | b | ISNULL ----+----+-------- 20 | 30 | 50 10 | 20 | -1 20 | 30 | 40 (3 rows)
处理列标题
fcsvparser 允许您使用 HEADER_NAMES=
参数指定您自己的列标题。此参数完全替换 CSV 源标题行中的列名。
例如,要将这六个列标题用于您正在加载的 CSV 文件,请使用 fcsvparser 参数,如下所示:
HEADER_NAMES='FIRST, LAST, SOCIAL_SECURITY, TOWN, STATE, COUNTRY'
如果提供比现有数据列更少的标题名称,则 fcsvparser 在您提供的名称之后使用默认名称。默认标题名称由
ucoln
组成,其中 n 是列偏移量,第一列从 0
开始。例如,如果您为 6 列表提供四个标题名称,fcsvparser 会在您提供的第四个标题名称之后提供默认名称 ucol4
和 ucol5
。
如果您提供的标题多于现有表列,则任何其他标题都将保持未使用状态。