格式化Greenplum中的外部表(PostgreSQL)

时间:2012-11-05 15:07:28

标签: database postgresql greenplum

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

例如,使用Oracle我可以使用DATE_FORMAT DATE MASK'YYYYMMDD'来告诉如何解析日期。对于Netezza,我可以指定DATESTYLE'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 '')

2 个答案:

答案 0 :(得分:2)

您似乎可以:

SET DATESTYLE = 'YMD';

SELECT表之前。但这会影响所有日期的解释,而不仅仅是文件中的日期。如果您一直在其他地方使用明确的ISO日期,那么这可能是一个问题,但如果(例如)您还需要接受“D / M / Y'同一查询中的日期文字。

这是GreenPlum的CREATE EXTERNAL TABLE特有的,不适用于SQL标准的SQL/MED外来数据包装器,如下所示。


让我感到惊讶的是,PostgreSQL本身(没有此CREATE EXTERNAL TABLE功能)始终接受ISO样式的YYYY-MM-DDYYYYMMDD日期,无论DATESTYLE。观察:

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 file_fdw SQL/MED foreign data wrapper

的工作原理
CREATE EXTENSION file_fdw;

COPY (SELECT '20121229', '2012-12-29') TO '/tmp/dates.csv' CSV;

SET DateStyle = 'DMY';

CREATE SERVER csvtest FOREIGN DATA WRAPPER file_fdw;

CREATE FOREIGN TABLE csvtest (
    date1 date,
    date2 date
) SERVER csvtest OPTIONS ( filename '/tmp/dates.csv', format 'csv' );

SELECT * FROM csvtest ;
   date1    |   date2    
------------+------------
 2012-12-29 | 2012-12-29
(1 row)

CSV文件内容为:

20121229,2012-12-29

因此您可以看到Pg将始终接受CSV的ISO日期,而不考虑日期风格。

如果GreenPlum没有,请提交错误。 DateStyle改变创建后读取外表的方式的想法很疯狂。

答案 1 :(得分:0)

是的,你可以。

您可以通过将外部表中的字段指定为text类型来执行此操作。然后,在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