この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
DA事業本部での研修として最後のプレゼンを終えました、新卒エンジニアのたいがーです?
AWS LambdaでDynamoDBにデータを入れたけど、データウェアハウスとしてAmazon Redshiftにデータを置きたい!Amazon DynamoDBに入れたデータに対して複雑なSQL関数を使いまくりたい!という時ありますよね!そんな時、RedshiftでCOPYコマンドを実行することで解決できます。
データウェアハウスってなんだ?という方は、是非こちらの動画をご覧ください!
今回は初めにDevelopers.IOのRSSフィードを使用して、DynamoDBのテーブルを作成します。次にCOPYコマンドを使って、DynamoDBテーブルからRedshiftにデータをロードしてみたいと思います。
開発環境
- boto3 v1.16.37
- Python v3.8.2
事前準備
DynamoDBテーブルの作成
まず初めにDynamoDBテーブルを作成します。
- Title
- パーティションキー
- Author
- ソートキー
- URL
- Tags
DynamoDBテーブルの作成
import boto3
import feedparser
client = boto3.client('dynamodb')
def put_tag():
create_table()
waiter = client.get_waiter('table_exists')
waiter.wait(TableName='cm-tiger-DevIO')
put_items()
def put_items():
dev_io = feedparser.parse('https://dev.classmethod.jp/feed/')
entries = dev_io['entries']
try:
resource = boto3.resource('dynamodb')
table = resource.Table('cm-tiger-DevIO')
with table.batch_writer() as batch:
for entry in entries:
batch.put_item(
Item={
'Title': entry['title'],
'Author': entry['author'],
'URL': entry['link'],
'Tags': entry['tags'][-1]['term'] if 'tags' in entry else ''
}
)
except Exception as error:
print(error)
def create_table():
client.create_table(
TableName='cm-tiger-DevIO',
AttributeDefinitions=[
{
'AttributeName': 'Title',
'AttributeType': 'S'
},
{
'AttributeName': 'Author',
'AttributeType': 'S'
}
],
BillingMode='PAY_PER_REQUEST',
KeySchema=[
{
'AttributeName': 'Title',
'KeyType': 'HASH'
},
{
'AttributeName': 'Author',
'KeyType': 'RANGE'
},
]
)
put_tag()
実行結果
続いてCOPYコマンドで使用するIAMロールを作成していきます。
IAMロールの作成
IAMロール(cm-tiger-copy-redshift)を作成し、IAMポリシーはこちらの2つを付与します。
- AmazonRedshiftQueryEditor
- AmazonDynamoDBReadOnlyAccess
作成したIAMロールをRedshiftクラスターのプロパティからアクセス許可します。
RedshiftのクラスターにIAMロールのアクセスを許可する
Redshiftのクラスターのプロパティ設定からIAMロールの管理を選択し、IAMロールを追加します。実際にCOPYコマンドを実行していきたいと思います。状態がin-sync
になっていることを確認してください。
クエリエディタを使用してDynamoDBからRedshiftにロードする
今回は、クエリエディタを使用してクエリを実行していきたいと思います。
テーブルを作成する
まず、Redshift内のデータベースにテーブルを作成します。このとき、Redshiftのデータベース内に作成するテーブルのカラム名はDynamoDBテーブルの属性名と同じにする必要があります。
テーブルの作成(1)
create table public.cm_tiger_DevIO_Title (Title varchar(max), Author varchar(max), URL varchar(max), Tags varchar(max));
次に、 Dynamo DBとIAM ロールを指定し、Redshiftのテーブルにコピーします。
DynamoDBテーブルからRedshiftにCOPYする
copy public.cm_tiger_DevIO_list
from 'dynamodb://cm-tiger-DevIO-List'
iam_role 'arn:aws:iam::XXXXXXXXXXX:role/cm-tiger-copy-redshift'
readratio 50;
テーブルの表示(1)
select * from public.cm_tiger_DevIO_list
COPYコマンドを使用する時、DynamoDBのテーブルの一部のみをロードすることも可能です。
テーブル作成時にカラム名を変えると一部だけ取り出すことができる
テーブル作成時でDynamoDBで作成した属性の一部を指定すると、COPY時にそのカラムのみをコピーすることが可能です。
テーブルの作成(2)
create table public.cm_tiger_DevIO_Title (Title varchar(max), Author varchar(max), URL varchar(max), Tags varchar(max));
DynamoDBテーブルからRedshiftにCOPYする
copy public.cm_tiger_DevIO_list
from 'dynamodb://cm-tiger-DevIO-Title'
iam_role 'arn:aws:iam::XXXXXXXXXXX:role/cm-tiger-copy-redshift'
readratio 50;
テーブルの表示(2)
select * from public.cm_tiger_DevIO_Title
このように、テーブル作成時にRedshiftに格納するデータを指定することが可能です。
COPY実行時のDynamoDBの読み込みCapacity
今回クエリで返された値は22件で、このようなCapacityになりました。
とても便利なCOPYコマンド
テーブル作成時にカラムを指定するだけで指定した属性をコピーしてくれるのはとても便利ですよね!是非みなさんも試してみて下さい。
以上、たいがーでした?