Database 在Greenplum(PostgreSQL)中格式化外部表

Database 在Greenplum(PostgreSQL)中格式化外部表,database,postgresql,greenplum,Database,Postgresql,Greenplum,我想使用外部表将一个普通文件加载到Greenplum数据库中。 我可以为时间戳/日期/时间字段指定输入格式吗?如果你知道PostgreSQL的答案,也请回复 例如,对于Oracle,我可以使用DATE_格式的日期掩码“YYYYMMDD”来说明如何解析日期。对于Netezza,我可以指定日期样式“YMD”。对于Greenplum,我找不到答案。我可以将字段描述为char,然后在加载过程中解析它们,但这是一个糟糕的解决方法 这是我的暂定代码: CREATE EXTERNAL TABLE MY_TBL

我想使用外部表将一个普通文件加载到Greenplum数据库中。 我可以为时间戳/日期/时间字段指定输入格式吗?如果你知道PostgreSQL的答案,也请回复

例如,对于Oracle,我可以使用DATE_格式的日期掩码“YYYYMMDD”来说明如何解析日期。对于Netezza,我可以指定日期样式“YMD”。对于Greenplum,我找不到答案。我可以将字段描述为char,然后在加载过程中解析它们,但这是一个糟糕的解决方法

这是我的暂定代码:

CREATE EXTERNAL TABLE MY_TBL (X date, Y time, Z timestamp ) 
LOCATION (
 'gpfdist://host:8001/file1.txt',
 'gpfdist://host:8002/file2.txt'
) FORMAT 'TEXT' (DELIMITER '|' NULL '')
是的,你可以

可以通过将外部表中的字段指定为文本类型来完成此操作。然后,在insert语句中使用转换。您还可以使用gpload并定义转换。这两种解决方案与上述解决方案类似

下面是一个简单的文件,其中包含一个整数和一个以年-月-日表示的日期,用空格分隔:

date1.txt

1|2012 10 12
2|2012 11 13
启动gpfdist:

gpfdist -p 8010 -d ./ -l ./gpfdist.log &
使用psql创建外部表、目标表并加载数据:

psql test

test=# create external table ext.t2( i int, d text ) 
  location ('gpfdist://walstl-mbp.local:8010/date1.txt') 
  format 'TEXT' ( delimiter '|' )
;


test=# select * from ext.t2; i |     d      
---+------------
  1 | 2012 10 12
  2 | 2012 11 13
(2 rows)
现在,创建数据将加载到的表:

test=# create table test.t2 ( i int, d date ) 
;
然后,加载表格:

test=# insert into test.t2 select i, to_date(d,'YYYY MM DD') from ext.t2 ;

test=# select * from test.t2;
 i |     d      
---+------------
 1 | 2012-10-12
 2 | 2012-11-13

看来您可以:

SET DATESTYLE = 'YMD';
在从表中选择之前。但这将影响所有日期的解释,而不仅仅是文件中的日期。如果您在其他地方一直使用明确的ISO日期,这将很好,但如果您需要在同一查询中同时接受“D/M/Y”日期文字,则可能会出现问题

这是特定于GreenPlum的CreateExternalTable的,不适用于SQL标准SQL/MED外部数据包装器,如下所示

令我惊讶的是,PostgreSQL本身没有此创建外部表功能,它总是接受ISO样式的YYYY-MM-DD和YYYYMMDD日期,而不考虑日期样式。注意:

regress=> SELECT '20121229'::date, '2012-12-29'::date, current_setting('DateStyle');
    date    |    date    | current_setting 
------------+------------+-----------------
 2012-12-29 | 2012-12-29 | ISO, MDY
(1 row)

regress=> SET DateStyle = 'DMY';
SET
regress=> SELECT '20121229'::date, '2012-12-29'::date, current_setting('DateStyle');
    date    |    date    | current_setting 
------------+------------+-----------------
 2012-12-29 | 2012-12-29 | ISO, DMY
(1 row)
。。。因此,如果GreenPlum的行为与此相同,则不需要做任何事情来从输入文件中正确读取这些YYYYMMDD日期

以下是它如何与PostgreSQL配合使用:

CSV文件内容包括:

20121229,2012-12-29
所以您可以看到,Pg将始终接受CSV的ISO日期,而不考虑日期样式


如果GreenPlum没有,请提交一个bug。DateStyle在创建后更改外部表的读取方式的想法是疯狂的。

您可以设置DateStyle='YMD';在加载带有副本的CSV之前,但我不确定是否有外部表。说得好。创建外部表时有效的日期样式是否保留?如果在创建外部表后对其进行更改,会发生什么情况?SET-DATESTYLE也适用于从外部表读取。那有帮助!非常感谢。它在创建表后选择期间应用。看起来这是控制格式的唯一方法-全局控制格式。-你能把它作为一个答案吗?顺便说一句,这并不适用于PostgreSQL本身。在PostgreSQL中,您将使用文件_fdwforeign data wrapper,因为没有创建外部表。我在问题中指出,有一种方法可以将字段定义为char,然后在加载过程中对其进行解析-但这是一种可能不需要的解决方法,例如,我的实用程序创建外部表,用户代码负责将其加载到永久表中。您不能为外部表指定“DISTRIBUTED BY”,只能为内部表指定-此选项告诉Greenplum如何在加载到持久性内部表期间将您的表存储到bucket中。您还可以为可写外部表指定DISTRIBUTED BY,但不能为我使用的用于读取的表指定DISTRIBUTED BY
20121229,2012-12-29