DynamoDB テーブルを CSV にエクスポートする方法(4 つの方法)
DynamoDB にはネイティブの「CSV にエクスポート」ボタンがありません。すべての値は
DynamoDB のマーシャリングされた JSON — {"S": "..."}、
{"N": "123"}、{"M": {...}} — で包まれて返ってきて、テーブルにはフラットな列の
明白な表現を持たないネストしたマップ、リスト、セットが格納されることがあります。
そのため「DynamoDB を CSV にエクスポート」は実際には 2 つの問題です。アイテムを
取り出す、そして 型付き JSON を行にフラット化する。コンソールもマネージド
エクスポートも、2 番目のステップをあなたのためにやってはくれません。
本ガイドでは、テーブルサイズと、アイテムが持つネストの量によって 4 つのアプローチを 順位づけします。
DynamoDB テーブルを CSV にエクスポートするにはどうすればよいですか?
DynamoDB にはネイティブの CSV エクスポート機能がないため、テーブルをスキャンまたはスナップショットし、型付き JSON を行にフラット化する必要があります。小さなテーブルには AWS CLI の scan + jq または短いスクリプトを使い、大きなテーブルは S3 にエクスポートして変換します。フィルタ済みですぐに使える CSV が必要な場合は、DynoTable のような GUI を使用してください。
- 小さなテーブル、アドホック: AWS CLI
scan+jq、または 20 行のスクリプト (方法 1 / 方法 3)。 ネストした属性が現れるまでは問題ありません。 - 大きなテーブル(GB 以上): DynamoDB の S3 へのエクスポート (方法 2)、その後ダンプを変換します。 非同期で実行され、読み取りキャパシティを消費しません — ただし出力は CSV ではなく DynamoDB JSON です。
- フィルタ / 整形された CSV(列の一部、一部のアイテムのみ): GUI エクスポートか スクリプト。マネージドの S3 エクスポートは テーブル全体 を、フィルタなしで返します。
方法 1: AWS CLI scan + jq
小さなテーブルなら、スキャンして jq で出力を整形できます。Scan はテーブルまたは
インデックス内の すべてのアイテム を読み取り、最大 1 MB のページで返します。
CLI はページネーションを自動的にたどります
(AWS ドキュメント: テーブルのスキャン)。
aws dynamodb scan --table-name MyTable --output json \
| jq -r '.Items[] | [.id.S, .name.S, .price.N] | @csv' \
> out.csv落とし穴はその jq の行にあります。各属性の 型記述子(S、N、B、BOOL、M、
L、SS、NS、BS)の先を掘って生の値を得るために、.id.S、.name.S、.price.N を
手で書く必要があります。3 つの文字列列を持つフラットなテーブルなら扱えます。
次のものが現れた瞬間に崩壊します。
- ネストしたマップ / リスト —
{"M": {...}}や{"L": [...]}にはフラット化する 単一の列がありません。@csvが詰まるか、セルを手で JSON エンコードすることになります。 - セット —
{"SS": ["a","b"]}はスカラーではなく配列です。 - 疎な属性 — DynamoDB はスキーマレスなので、アイテム A には
priceがあり、 アイテム B にはないことがあります。固定の列リストは、列を黙って落とすか、ずらします。
また、DynamoDB の型を理解する --output csv はありません。CLI の csv 出力は 生の
レスポンスを、記述子もすべて含めてフラット化します — そのため、型タグを剥がすには
やはり jq(またはスクリプト)が必要です。これが、「AWS CLI で DynamoDB テーブルを
CSV にエクスポート」が自明なケースを超えると決してワンライナーにならない核心的な理由です。
このやり方でより大きなテーブル全体を一日がかりにせずエクスポートするには、--segment /
--total-segments でスキャンを並列化し
(AWS ドキュメント: パラレルスキャン —
DynamoDB は「各アイテムのパーティションキーにハッシュ関数を適用してアイテムを セグメント に
割り当てる」ので、セグメントは不均等になり得ます)、最初の 1 MB ページで止まらないよう
ページネーションを読んでください。
方法 2: DynamoDB の S3 へのエクスポート(大きなテーブル)
実際に大きなテーブルには、マネージドの Amazon S3 へのエクスポート が適切なツール です。ポイントインタイムリカバリ(PITR) ウィンドウ内の任意の時点からスナップショットを エクスポートし — そのためテーブルでまず PITR を有効にする必要があります — 非同期で 実行され、読み取りキャパシティユニットを消費しない ため、テーブルのスループットや 可用性にゼロの影響です(AWS ドキュメント: 「エクスポートは非同期であり、読み取りキャパシティユニット(RCU)を消費せず、テーブルの パフォーマンスと可用性に影響しない」、「エクスポート機能を使うにはテーブルで PITR を 有効にする必要がある」)。これはコンソールの S3 へのエクスポート アクションが内部で トリガーするものでもあります。コンソールは同じ API のフロントエンドにすぎないので、 同じ PITR 要件と同じ JSON 出力を引き継ぎます。
aws dynamodb export-table-to-point-in-time \
--table-arn arn:aws:dynamodb:us-east-1:123456789012:table/MyTable \
--s3-bucket my-export-bucket \
--export-format DYNAMODB_JSON唯一の落とし穴: S3 エクスポートは CSV を出力しません。 DynamoDB JSON または
Amazon Ion のみを、JSON-lines形式(1 行 1 アイテム)の
gzip ファイルとして、マニフェストファイルとともに書き出します
(AWS ドキュメント: エクスポート出力形式 —
データファイルは .json.gz として書かれ、「形式は JSON lines」で、
manifest-summary.json / manifest-files.json とともに)。その後にやはり変換ステップが
必要です。
- Athena / Glue は、エクスポートされた DynamoDB JSON を直接読みます — S3 プレフィックスに
テーブルを向け、
SELECTから CSV を書き出します(これが通常の「DynamoDB を S3 に、 それから CSV に」エクスポートするパイプラインです)。AWS は「Athena や AWS Glue など多くの AWS サービスがこの形式を自動的にパースする」と述べています (エクスポート出力形式)。 - 自前で実装 —
.gzファイルを展開し、各 JSON 行をパースし、フラット化します (他のすべての方法と同じフラット化問題)。
これはまた テーブル全体 のスナップショットです。一部のアイテムだけをエクスポートする サーバー側フィルタはありません。サブセットが必要なら、後で Athena でフィルタするか、 スクリプト / GUI を使います。
方法 3: 手早いスクリプト(boto3 / Node)
整形された CSV — 特定の列、フィルタされたサブセット、ネストフィールドのカスタム処理 — が
必要なときは、小さなスクリプトが jq との格闘に勝ります。利点は、AWS SDK が型付き JSON を
アンマーシャリング してくれることです。boto3 のリソースインターフェースと JS SDK の
DynamoDBDocumentClient は、{"price": {"N": "2000"}} ではなく素の {"price": 2000} を
返します(boto3 のリソースインターフェースは「データの型付けを暗黙的にする」、
AWS Python ガイドより。
JS の DocumentClient は「注釈付きのレスポンスデータをネイティブの JavaScript 型に変換する」、
@aws-sdk/lib-dynamodbより)。
import boto3, csv
table = boto3.resource("dynamodb").Table("MyTable")
rows, resp = [], table.scan()
rows += resp["Items"]
while "LastEvaluatedKey" in resp: # 最後までページネーション
resp = table.scan(ExclusiveStartKey=resp["LastEvaluatedKey"])
rows += resp["Items"]
with open("out.csv", "w", newline="") as f:
w = csv.DictWriter(f, fieldnames=["id", "name", "price"])
w.writeheader()
for r in rows:
w.writerow({k: r.get(k) for k in w.fieldnames})それでも SDK があなたの代わりに決められない 2 つの判断は自分のものです。ネストした
マップ / リストをどう フラット化 して列にするか(セルを JSON エンコードする? キーを
ドットパスにする?)、そして 疎な 属性をどうするか(ここでは欠けているキーは
r.get(k) で空のセルになります)。そして LastEvaluatedKey のループを落とさないこと —
1 回の scan() 呼び出しは最初の 1 MB ページだけを返すので、それがないとテーブルの一部を
黙ってエクスポートしてしまいます。
方法 1 と同じ注意点: ここでのフルテーブル scan もやはり読み取りキャパシティを消費し、
ライブトラフィックと競合します。大きなテーブルには
方法 2 を選び、ダンプを整形してください。
方法 4: DynoTable でのワンクリックエクスポート
スクリプトと CLI のルートは機能しますが、毎回同じフラット化とページネーションのロジックを 作り直すことになります。DynoTable はそれをあなたの代わりにやります。クエリを 実行またはフィルタし、表示中の行をそのまま CSV(または Excel)にエクスポートします — 型記述子は展開され、ネストしたマップとリストはフラット化され、セットは処理され、出力には 実際に欲しいアイテムと列だけが入ります。
現在のビュー をエクスポートするので、 方法 2 のテーブル全体スナップショットでは 得られない、フィルタ / 整形された CSV が — スキャンループを書かずに — 手に入ります。 これはデスクトップの DynamoDB クライアントであり、あなたがすでにテーブルを閲覧するのに 使っているのと同じツールです。他の DynamoDB GUI とどう比較されるかをご覧ください。
落とし穴: DynamoDB JSON とフラットな CSV
どの方法を選んでも、DynamoDB のデータモデルとフラットな CSV の間の同じ一握りの不一致が あなたを噛みます。
- 型記述子。 生の API / CLI / S3 エクスポートの出力は、すべての値を包みます
(
{"S": "..."}、{"N": "123"})。SDK でアンラップするか、記述子を自分で剥がします。 完全なセットはS、N、B、BOOL、NULL、M、L、SS、NS、BSです — DynamoDB のデータ型を参照してください。 - ネストしたマップとリスト(
M、L)は最大 32 レベルの深さ までネストでき (AWS ドキュメント: データ型 — リストとマップは「互いにネストでき、最大 32 レベルの深さの複雑なデータ構造を表現できる」)、 自然な単一列の形がありません。事前に決めましょう: セルを JSON エンコードするか、 ネストしたキーをドットパスの列(address.city)に展開するか。 - セット(
SS/NS/BS)は 順序のない コレクションであり、スカラーではありません — AWS は「セット内の値の順序は保持されない」と警告します (データ型)— そのため区切り文字列にフラット化し、要素の順序に依存しないでください。 - 疎な属性。 DynamoDB はスキーマレスなので、2 つのアイテムが異なる属性を持てます。 固定の列セットはありません。すべてのアイテムにわたってキーを和集合にしないと列がずれます。 これは シングルテーブル設計の直接的な帰結であり、 1 つのテーブルが複数のエンティティ形状を保持します。
- ページネーション。
Scan(とQuery)は 1 回の呼び出しで最大 1 MB を返します。LastEvaluatedKeyでループしないと、最初のページだけを黙ってエクスポートします。 ページネーションを参照してください。 - 数値の精度。 DynamoDB の数値は最大 38 桁 の精度を持ち、文字列として伝わります (AWS ドキュメント: データ型: 「数値は最大 38 桁の精度を持てる」、「すべての数値は文字列としてネットワーク越しに DynamoDB に送られる」)。スプレッドシートソフトは長い数値や ID を浮動小数点数に 強制変換して桁を失うことがあります。テキストのまま保ってください。
FAQ
AWS CLI で DynamoDB テーブルを CSV にエクスポートするには?
テーブルをスキャンし、出力を jq で整形します(方法 1): aws dynamodb scan →
各値の型記述子を剥がす jq → @csv。DynamoDB を理解する --output csv はないので、
型剥がしは常に自分で行い、ネストしたマップ、リスト、セットでは壊れます。
AWS から DynamoDB テーブルを直接 CSV にエクスポートできる?
1 ステップではできません。コンソールもマネージド S3 エクスポートも DynamoDB JSON または
Amazon Ion を生成し、CSV にはなりません。常に変換ステップが必要です — CLI + jq、
スクリプト、S3 ダンプ上の Athena/Glue、またはフラット化をやってくれる GUI。
本番に影響を与えずに DynamoDB テーブル全体をエクスポートするには?
S3 へのエクスポート 機能(方法 2)を使います。非同期で実行され、読み取りキャパシティ
ユニットを消費しない ので、ライブトラフィックと競合しません — テーブルのスループットに
課金される Scan と異なり
(AWS ドキュメント)。
PITR の有効化が必要で、フィルタされたサブセットではなくテーブル全体をエクスポートします。
DynamoDB を S3 に CSV としてエクスポートするには?
マネージドエクスポートは DynamoDB JSON / Ion を S3 に書くだけなので、「CSV に」は 2 ホップ目です。
エクスポートプレフィックスを Athena(または Glue)テーブルとして登録し、SELECT から
CSV を書き出します。--export-format CSV はありません。
DynamoDB を Excel にエクスポートするには?
まず CSV にエクスポートし(上記いずれかの方法)、その CSV を Excel で開きます — 長い
数値 ID が浮動小数点数に強制されないようテキストのまま保ちます。DynamoDB から直接の
.xlsx エクスポートはありません。DynoTable のような GUI は、現在のビューを
スプレッドシート対応の CSV として直接保存できます。
エクスポートした JSON に {"S": ...} や {"N": ...} があちこちにあるのはなぜ?
それは DynamoDB のマーシャリングされたワイヤ形式です — 各値が型記述子でタグ付けされて
います。CSV を書く前に、SDK、DynamoDB JSON コンバーター、
または GUI でアンマーシャリングします。データが API、CLI、S3 エクスポートのどこから来ても、
ワイヤ形式は同じです。
自分のテーブルを閲覧、フィルタし、CSV にエクスポートするには DynoTable を、 あるいはまず DynamoDB JSON のサンプルを JSON コンバーターで展開してみてください。