Help us improve the AWS re:Post Knowledge Center by sharing your feedback in a brief survey. Your input can influence how we create and update our content to better support your AWS journey.
AWS Glue クローラーの実行中に複数のテーブルが作成されないようにする方法を教えてください。
AWS Glue クローラがソースデータから複数のテーブルを作成しています。この状況が今後起こらないようにするための対応策を知りたいです。
簡単な説明
AWS Glue クローラーの初回実行時に、クローラーはスキーマを推測するために各ファイルの最初の 1000 レコードまたは最初の 1 メガバイトを読み取ります。クローラーが読み取るデータ量は、ファイル形式と有効なレコードの有無に左右されます。
たとえば、入力が JSON ファイルの場合、クローラーはファイルの最初の 1 MB を読み取ります。クローラーがファイルの最初の 1 MB 内の有効なレコードを読み取ると、クローラーはスキーマを推測します。クローラーがスキーマを推測できない場合、クローラーは 1 MB ずつ、最大 10 MB のファイルを読み取ります。
.csv ファイルでは、クローラーは最初の 1000 レコードまたは最初の 1 MB のレコードを基準にデータを読み取ります。Parquet ファイルでは、クローラーはファイルから直接スキーマを推測します。
クローラーは、すべてのサブフォルダとファイルから推測したスキーマを比較し、テーブルを作成します。
ソースデータファイルが以下のパラメータに同じ構成を使用していない場合、クローラーは複数のテーブルを作成します。
- フォーマット (.csv、Parquet、JSON など)
- 圧縮タイプ (SNAPPY、gzip、bzip2 など)
- スキーマ
- Amazon Simple Storage Service (Amazon S3) パーティションの構造
解決策
クローラーのログを確認する
クローラーが複数のテーブルを作成する原因となるファイルを特定するには、次の手順を実行します。
- AWS Glue コンソールを開きます。
- ナビゲーションペインで、[クローラー] を選択します。
- 確認するクローラーを選択します。
- [ログ] リンクをクリックして Amazon CloudWatch コンソールにログを表示します。
AWS Glue が前回のクローラー実行中に複数のテーブルを作成した場合、ログには次のようなエントリが含まれます。
[439d6bb5-ce7b-4fb7-9b4d-805346a37f88] INFO : Created table
2_part_00000_24cab769_750d_4ef0_9663_0cc6228ac858_c000_snappy_parquet
database glue
[439d6bb5-ce7b-4fb7-9b4d-805346a37f88] INFO : Created table
2_part_00000_3518b196_caf5_481f_ba4f_3e968cbbdd67_c000_snappy_parquet in
database glue
[439d6bb5-ce7b-4fb7-9b4d-805346a37f88] INFO : Created table
2_part_00000_6d2fffc2_a893_4531_89fa_72c6224bb2d6_c000_snappy_parquet in
database glue
ログエントリには、クローラーが複数のテーブルを作成する原因となるファイルの名前が含まれます。
複数のテーブルが作成されないようにする
複数のテーブルが作成されないようにするには、ユースケースに応じて次のいずれかのアクションを実行してください。
データファイルが同じスキーマ、フォーマット、圧縮タイプを使用していることを確認する
ファイルが複数のスキーマを使用する場合があります。たとえば、スキーマ A はフィールド X が INT 型であると見なし、スキーマ B はフィールド X が BOOL 型であると見なす場合があります。
このユースケースでは、 from_options 関数を使用して AWS Glue の抽出、変換、ロード (ETL) ジョブを実行し、外れ値データを読み取ります。次に、外れ値のデータ型をソースにおける正しいデータ型または最も一般的なデータ型に変換します。
既存のテーブル DDL を使用して Amazon Athena にテーブルを手動で作成することもできます。次に、AWS Glue クローラーを実行してテーブルのメタデータを更新します。テーブルの既存のスキーマを上書きしないようにクローラーを構成します。
**クローラーの作成時に、互換性のあるスキーマを組み合わせる **
クローラーはフォルダレベルでスキーマを推測し、すべてのフォルダのスキーマを比較します。クローラーは、スキーマが一致しており、パーティションのしきい値が 70% を超えているかどうかを確認します。一致する場合、スキーマはテーブルのパーティションとして示されます。一致しない場合、クローラーはフォルダごとにテーブルを作成するため、テーブルの数が多くなります。
一部の入力ファイルではデータのスキーマが異なり、他のファイルでは同様のスキーマが使用されている場合があります。クローラーを作成するときは、互換性のあるスキーマを組み合わせてください。
AWS Glue コンソールの [クローラーの出力設定] ページにある [S3 データのグループ化動作 (オプション)] で、[S3 パスごとに単一のスキーマを作成する] を選択します。データに互換性がある場合、クローラーはパス内の Amazon S3 オブジェクトを評価するときにスキーマの類似性を無視します。
詳細については、「Amazon S3 インクルードパスごとに単一のスキーマを作成する」を参照してください。
入力ファイルに複数の Amazon S3 パスがあるかどうかを確認する
Amazon S3 プレフィックス内の構造に一貫性がない場合、クローラーは各パスを個別のテーブルと見なします。その場合、クローラーは複数のテーブルを作成します。入力ファイルの Amazon S3 構造またはパスが複数種類ある場合、クローラーはデフォルトで複数のテーブルを作成します。
次のようなパーティション構造の s3://doc-example-bucket/doc-example-key/doc-example-table Amazon S3 パスでクローラーを実行する場合を例に挙げます。
- s3://doc-example-bucket/doc-example-key/doc-example-table/dt=2020-08-20/doc-example-file1.csv
- s3://doc-example-bucket/doc-example-key/doc-example-table/dt=2020-08-21/dox-example-file2.csv
- s3://doc-example-bucket/doc-example-key/doc-example-table/dt=2020-08-22/doc-example-file3.csv
次に、上記の 3 つのファイルに次のファイルを追加します。
- s3://doc-example-bucket/doc-example-key/doc-example-table/dox-example-file4.csv
- s3:// doc-example-bucket/doc-example-key/doc-example-table/doc-example-file5.csv
フォルダのパーティション構造に一貫性がないため、クローラーは新たなクローラー実行で 5 つの個別のテーブルを作成します。
この問題を回避するには、スキーマの一貫性を手動またはプログラムで確認します。上記の例では、dt=xxxx-xx-xx パーティションのない Amazon S3 ファイルを削除するか、doc-example-file4.csv ファイルと doc-example-file5.csv ファイル用のパーティションを追加します。不要なファイルやフォルダを除外するには、除外パターンを使用します。
一貫性のあるヘッダーを使用する
.csv 形式のデータを使用する場合は、一貫性のある方法でヘッダーを使用してください。一部のファイルにヘッダーがあり、他のファイルにはない場合、クローラーは複数のテーブルを作成します。
クローラーの実行で作成された複数のテーブルを削除する
CloudWatch ログで、クローラーの実行によるテーブルをフィルター処理します。次に、BatchDeleteTable API を呼び出してテーブルを削除します。
次の手順を実行します。
- AWS Glue コンソールを開きます。
- ナビゲーションペインで、[クローラー] を選択します。
- [クローラーの実行] で、ターゲットクローラー名を選択します。
- [実行の詳細を表示] を選択します。
- [クローラー実行の詳細] ページで、BatchDeleteTable 呼び出しで使用するクローラー実行の ID を書き留めておきます。
- [CloudWatch ログ] を選択し、ロググループ /aws-glue/crawlers を選択します。
- [アクション] を選択し、[Amazon S3 にデータをエクスポート] を選択します。
- 次の情報を入力してデータをエクスポートします。
[時間範囲] には、クローラー実行の開始時間と終了時間を使用します。
[ストリームのプレフィックス] には、クローラー名を追加します。
ターゲット S3 バケットとプレフィックスを選択し、クローラー実行ログをエクスポートします。 - ロググループ /aws-glue/crawlers で [アクション] を選択し、[Amazon S3 へのすべてのエクスポートを表示] を選択します。
- ロググループ /aws-glue/crawlers とターゲット S3 バケットのエクスポートタスクを選択します。
- [Amazon S3 で表示] を選択します。
- Amazon S3 コンソールで、ターゲットクローラー名のフォルダを選択します。
- エクスポートされたログファイルを .gz 形式でローカルマシンまたは Amazon Elastic Compute Cloud (Amazon EC2) インスタンスにダウンロードします。次に、ファイルをローカルパスに解凍します。BatchDeleteTable 呼び出しで使用するパスの場所を書き留めます。
- ローカルマシンまたは EC2 インスタンスから解凍されたファイルをスキャンしてテーブルをフィルター処理します。
- AWS Glue BatchDeleteTable API を呼び出してテーブルを削除します。
スクリプト例:
import boto3 import re # input parameters catalogId='CatalogId' database = 'databaseName' crawlId= 'crawlRunId' logFilePath = 'local_decompressed_file_path' # function to extract the created tables by the given crawl run id in target database def extract_table_info(file_path, target_crawl_id, target_database): list_tables = [] with open(file_path, 'r') as file: for line in file: match = re.search(f'.*\\[{target_crawl_id}\\] INFO : Created table (\\w+(?:_[a-f0-9]+)*) in database {target_database}', line) if match: table_name = match.group(1) list_tables.append(table_name) return list(set(list_tables)) createdTables = extract_table_info(logFilePath, crawlId, database) # initialize the Glue client and make batch_delete_table API calls to delete the created tables client = boto3.client('glue') for i in range(len(createdTables) // 100 + 1): tables_to_delete = createdTables[100 * i : 100 * (i + 1)] response = client.batch_delete_table( CatalogId=catalogId, DatabaseName=database, TablesToDelete=tables_to_delete ) print(i) print(response)
注: 例の入力パラメータは、実際の入力パラメータに置き換えます。上記のサンプルスクリプトは、ローカルマシンまたは EC2 インスタンス用のデフォルトの AWS リージョン設定を使用しています。boto3 のリージョンを変更する場合は、「設定」を参照してください。
