Amazon Redshift: UNLOADコマンドでCSVの出力が可能になりました(=CSVオプションの新設)

小ネタです。

Amazon Redshiftの下記メンテナンスリリースにて、当エントリで紹介する機能の情報が告知されていました。

  • AWS Developer Forums: Amazon Redshift Maintenance (March 14th - April 5th 2019) その内容とは、『You can now UNLOAD the result of a query to one or more text files in CSV format to Amazon S3.(UNLOADコマンドで、検索結果をCSVフォーマットでAmazon S3に出力出来るようになりました)というものです。簡単にではありますが、その中身と挙動を確認してみたいと思います。

ありそうで無かったUNLOADコマンドの『CSV』オプション

えっ、そんな基本的なのって既に無かったっけ?と思いましたが、実は無かったんですねぇ...。下記は日本語版のAmazon Redshift UNLOADコマンドに関するドキュメントですが、

2019年03月28日現在、CSVオプションは存在していません。従来のUNLOADコマンドでは、CSVフォーマットのファイルを出力する際はDELIMITERオプションを指定するなどして対応する必要がありました。

UNLOAD ('select-statement')
TO 's3://object-path/name-prefix'
authorization
[ option [ ... ] ]

where option is

{ MANIFEST [ VERBOSE ] 
| HEADER
| DELIMITER [ AS ] 'delimiter-char' 
| FIXEDWIDTH [ AS ] 'fixedwidth-spec' }  
| ENCRYPTED
| BZIP2  
| GZIP     
| ADDQUOTES 
| NULL [ AS ] 'null-string'
| ESCAPE
| ALLOWOVERWRITE
| PARALLEL [ { ON | TRUE } | { OFF | FALSE } ]
| MAXFILESIZE [AS] max-size [ MB | GB ] ]
| REGION [AS] 'aws-region'

一方、英語版ドキュメント。こちらは2019年03月28日現在の内容でCSVオプションが存在しています。

UNLOAD ('select-statement')
TO 's3://object-path/name-prefix'
authorization
[ option [ ... ] ]

where option is

{ MANIFEST [ VERBOSE ] 
| HEADER

            
| [ FORMAT [AS] ] CSV
| DELIMITER [ AS ] 'delimiter-char' 
| FIXEDWIDTH [ AS ] 'fixedwidth-spec' }  
| ENCRYPTED
| BZIP2  
| GZIP     
| ADDQUOTES 
| NULL [ AS ] 'null-string'
| ESCAPE
| ALLOWOVERWRITE
| PARALLEL [ { ON | TRUE } | { OFF | FALSE } ]
| MAXFILESIZE [AS] max-size [ MB | GB ] ]
| REGION [AS] 'aws-region'

UNLOADコマンド CSVオプション出力実践

では実際に出力を試してみましょう。挙動としては以下の内容となるようです。

  • 区切り文字としてコンマ(,)を使用してCSVテキストファイルとしてアンロード
  • フィールドにカンマ、ダブルクオート、改行、キャリッジリターンが含まれる場合、該当フィールドはダブルクオートで囲まれる
  • データフィールド内のダブルクォートは(追加の)ダブルクオートでエスケープされる
  • FORMAT及びASキーワードはオプション
  • CSVDELIMITERまたはFIXEDWIDTHと一緒には使用出来ない

検証用に以下のデータを用意しました。11行目のものは若干込み入った内容(ダブルクオートや改行を含む)としています。

# SELECT * FROM public.captain_marvel_quotes ORDER BY id;
 id |                                         phrase                                          |    speaker     
----+-----------------------------------------------------------------------------------------+----------------
  1 | I'VE BEEN FIGHTING WITH ONE ARM BEHIND MY BACK. WHAT HAPPENS WHEN I'M FINALLY SET FREE? | Captain Marvel
  2 | I HAVE NOTHING TO PROVE TO YOU.                                                         | Captain Marvel
  3 | WE HAVE NO IDEA WHAT THREATS ARE OUT THERE. WE CAN'T DO THIS ALONE. WE NEED YOU.        | Nick Fury
  4 | HIGHER FURTHER FASTER, BABY.                                                            | Captain Marvel
  5 | I'M NOT GONNA FIGHT YOUR WAR, I'M GOING TO END IT.                                      | Captain Marvel
  6 | GRUNGE IS A GOOD LOOK FOR YOU.                                                          | Nick Fury
  7 | CALL ME YOUNG LADY AGAIN, AND I'M GONNA PUT MY FOOT IN A PLACE IT'S NOT SUPPOSED TO BE. | Maria Rambeau
  8 | IF THERE ARE LIVES AT STAKE, I'LL FLY THE PLANE.                                        | Carol Danvers
  9 | TELL THE SUPREME INTELLIGENCE THAT I'M COMING TO END IT. THE WAR, THE LIES, ALL OF IT.  | Captain Marvel
 10 | THIS ISN'T ABOUT FIGHTING WARS. IT'S ABOUT ENDING THEM.                                 | Mar-Vell
 11 | Carol Danvers said                                                                     +| ----------
    | "HIGHER FURTHER FASTER, BABY".                                                          | 
(11 rows)

CSVオプションを使ってUNLOADを実行。

# UNLOAD ('SELECT id, phrase, speaker FROM public.captain_marvel_quotes ORDER BY id')
TO 's3://xxxxxxxxxxxx/unload-csv-test/captain_marvel_quotes'
IAM_ROLE 'arn:aws:iam::111122223333:role/xxxx-redshift-role'
PARALLEL OFF
CSV;

INFO:  UNLOAD completed, 11 record(s) unloaded successfully.
UNLOAD
Time: 4760.980 ms

実行結果を確認。 カンマを含む4行目や5行目のデータ、また改行文字を含む11行目のデータはダブルクオートで値が囲まれ、また値中のダブルクオートもエスケープされている事が確認出来ました。

1,I'VE BEEN FIGHTING WITH ONE ARM BEHIND MY BACK. WHAT HAPPENS WHEN I'M FINALLY SET FREE?,Captain Marvel
2,I HAVE NOTHING TO PROVE TO YOU.,Captain Marvel
3,WE HAVE NO IDEA WHAT THREATS ARE OUT THERE. WE CAN'T DO THIS ALONE. WE NEED YOU.,Nick Fury
4,"HIGHER FURTHER FASTER, BABY.",Captain Marvel
5,"I'M NOT GONNA FIGHT YOUR WAR, I'M GOING TO END IT.",Captain Marvel
6,GRUNGE IS A GOOD LOOK FOR YOU.,Nick Fury
7,"CALL ME YOUNG LADY AGAIN, AND I'M GONNA PUT MY FOOT IN A PLACE IT'S NOT SUPPOSED TO BE.",Maria Rambeau
8,"IF THERE ARE LIVES AT STAKE, I'LL FLY THE PLANE.",Carol Danvers
9,"TELL THE SUPREME INTELLIGENCE THAT I'M COMING TO END IT. THE WAR, THE LIES, ALL OF IT.",Captain Marvel
10,THIS ISN'T ABOUT FIGHTING WARS. IT'S ABOUT ENDING THEM.,Mar-Vell
11,"Carol Danvers said
""HIGHER FURTHER FASTER, BABY"".",----------

まとめ

というわけで、Amazon RedshiftのUNLOADコマンド:CSVオプションが新しく使えるようになったよ、というお知らせでした。機能自体は既存コマンドオプションで実現出来ていたので特に不自由するものではありませんが、「今後はシンプルにCSVオプションを(シンプルに)利用出来るようになった」という事を頭の片隅に入れておいて頂けますと幸いです。

参考情報