QuickSightのデータセットを別アカウントへ移行する

# はじめに
QuickSightの分析やダッシュボードを別アカウントへ移行したいと思って方法を調べると、いくつか記事がヒットします。
分析のテンプレートを作ってそれを移行先から参照するというものですが、その分析に使われているデータセットを移行する方法については、
手で作るなどになっていてさらっと流されている記事が多いです。

データセットに計算フィールドを使っていたり型変換をしていたりしていると
移行先WEb画面にて手で同じように作るのは困難になりますので、
それをうまく移行する方法について記載します。

本記事ではデータセットの移行だけについて記載しており、
そのあとの分析やダッシュボードの移行については記載していませんのでご了承ください。

# 移行作業
以下の手順で移行します。
1. 移行元のデータセットIDを確認
1. 移行元にてデータセットをjson出力
1. 移行先にてデータソース作成
1. 上記で出力したjsonを元に移行先にてデータセット作成

以降、AWS CLIを使って操作するのですが、CloudShellから実行するのが手軽です。

## 移行元のデータセットIDを確認

分析の一覧を更新日の新しい順に出力して分析のIDを調べます。
```bash
aws quicksight list-analyses --aws-account-id FROM_ACCOUNT_ID | jq '.AnalysisSummaryList | sort_by(.LastUpdatedTime) | reverse'
```

その分析で使っているデータセットIDを調べます。

```bash
aws quicksight describe-analysis --aws-account-id FROM_ACCOUNT_ID --analysis-id ANALYSIS_ID | jq '.Analysis.DataSetArns'
```
```json
[
  "arn:aws:quicksight:ap-northeast-1:111111111111:dataset/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
  "arn:aws:quicksight:ap-northeast-1:111111111111:dataset/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
]
```
実行するとデータセットのARNが得られます。
末尾のUUID形式の部分がデータセットIDとなりますのでメモっておきます。


## 移行元でデータセットをjson出力
先ほどメモしたデータセットIDを元にコマンドを実行し、
データセットの詳細をjsonファイル(dataset.json)に出力します
```bash
aws quicksight describe-data-set --aws-account-id FROM_ACCOUNT_ID --data-set-id DATA_SET_ID  > dataset.json
```

## 移行先でデータソース作成
データセットのもとになるデータソースは移行先のAWSアカウントのQuickSight Webコンソールから手で作ります。

データソースの一覧を更新日の新しい順に表示
```bash
aws quicksight list-data-sources --aws-account-id TO_ACCOUNT_ID | jq '.DataSources | sort_by(.LastUpdatedTime) | reverse'
```
これによって得られた結果から目的のデータソースのArnをメモっておきます。

## 移行先でjsonを元にデータセット作成
データセットを作成するjsonファイルを作成します。

まずデータセットを作成するためのテンプレートを出力します。
```bash
aws quicksight create-data-set --generate-cli-skeleton > create_dataset.skeleton.json
```


このテンプレートに対して、先ほど移行元で出力したjson(dataset.json)を元に埋めていきます。
### 注意点
* KeyName
移行先のPhysicalTableMap.KeyName, LogicalTableMap.KeyNameは移行元のデータセットのもの（UUID形式の文字列）をそのまま入力します。

移行元でのjson
```json:dataset.json
        "PhysicalTableMap": {
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx": {
```
書き換えるべきテンプレート
```json:create_dataset.skeleton.json
    "PhysicalTableMap": {
        "KeyName": {      ←ここをxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxにする
```

* 計算フィールド
計算フィールド（LogicalTableMap.KeyName.DataTransforms.CreateColumnsOperation）では、
内部で別の計算フィールドを参照している場合、jsonの順序に気を付ける必要があります。  
```json
{
    "CreateColumnsOperation": {
        "Columns": [
            {
                "ColumnName": "column_A",
                "ColumnId": "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA",
                "Expression": "何かの計算式"
            }
        ]
    }
},
{
    "CreateColumnsOperation": {
        "Columns": [
            {
                "ColumnName": "column_B",
                "ColumnId": "BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB",
                "Expression": "column_Aを参照する計算式"
            }
        ]
    }
},
```  
このcolumn_Aとcolumn_Bの記載順序が逆だとCONTEXTUAL_UNKNOWN_SYMBOLのエラーで作成に失敗します。

### データセット作成
作成したjson(create_dataset.skeleton.json)を読み込ませ、データセットを作成します。
```bash
aws quicksight create-data-set --aws-account-id TO_ACCOUNT_ID --cli-input-json file://create_dataset.skeleton.json
```
以上です。

# おわりに
QuickSightのWebコンソールにて手で作って移行させるのも面倒なのですが、
本記事で記載したjsonでの移行も、jsonファイルの編集作業がなかなか大変な作業になります。
もっと簡単にエクスポート/インポートができるとよいのですが、、、