Traffine I/O

日本語

2022-10-02

RDS Data API

RDS Data APIとは

Amazon Web Services(AWS)は、多数のデータベースサービスを提供しており、そのうちの一つがAmazon Relational Database Service(RDS)です。RDS Data APIは、RDSの強力な機能の一つで、RDSデータベースにアクセスするための完全にマネージドなサーバーレスAPIを提供します。

RDS Data APIを使用すると、データベース接続や認証情報の管理を行う必要がなく、安全にRDSデータベースのデータをアクセス・変更することができます。

RDS Data APIは、AWS Lambda関数を使用してRDSデータベースに対するSQL文を実行するため、アプリケーションコードを簡素化し、メンテナンスを容易にします。さらに、RDS Data APIは、セキュリティ、スケーラビリティ、コスト効率の向上を提供します。

サーバーレスアプリケーション、マイクロサービス、モバイルアプリケーション、Webアプリケーションなど、多様な用途で利用可能なRDS Data APIは、データベースアクセスの簡素化とアプリケーションの効率化に貢献する貴重なツールです。

RDS Data APIのメリット

RDS Data APIは、データベースアクセスに多くのメリットを提供するAmazon RDSの強力な機能です。以下に、RDS Data APIの主なメリットをいくつか挙げます。

  • データベースアクセスの簡素化
    RDS Data APIを使用すると、データベース接続や認証情報の管理が不要になります。これにより、アプリケーションコードが簡素化され、保守が容易になります。

  • セキュリティの向上
    RDS Data APIは、AWS Identity and Access Management(IAM)を使用してRDSデータベースへのアクセスを制御します。IAMロールとポリシーを簡単に作成して、特定のリソースとアクションにアクセスを許可できます。

  • スケーラビリティ
    RDS Data APIは、完全に管理され、サーバーレスであるため、任意のトラフィック量に対応して自動的にスケールできます。

  • コスト効率の向上
    RDS Data APIを使用すると、リクエストした分だけ支払うため、データベースアクセスのコストを抑えることができます。

  • サーバーレスアプリケーション開発の簡素化
    RDS Data APIは、データベース接続や認証情報の管理が不要になるため、サーバーレスアプリケーションの開発に最適なオプションです。

  • マイクロサービスの拡張
    RDS Data APIを使用して、RDSデータベースにアクセスするマイクロサービスを構築できます。これにより、スケーラブルなアプリケーションの構築と保守が容易になります。

  • モバイルアプリケーションとWebアプリケーションの向上
    RDS Data APIを使用して、モバイルアプリケーションやWebアプリケーションからRDSデータベースに安全にアクセスしてデータを変更できます。

RDS Data APIの仕組み

以下がRDS Data APIの動作方法です。

  1. 実行環境
    RDS Data APIにリクエストを送信すると、AWS Lambdaが実行環境を作成します。

  2. SQL文
    SQL文をRDS Data APIに提供します。

  3. 接続
    AWS LambdaがRDSデータベースに接続します。

  4. SQL実行
    AWS LambdaがRDSデータベースでSQL文を実行します。

  5. 結果
    実行が完了すると、結果がアプリケーションに返されます。

このプロセスにより、データベース接続や認証情報の管理が不要になり、RDSデータベースへのアクセスがシンプルかつ効率的になります。RDS Data APIは、AWS IAMを使用して、RDSデータベースへのアクセスを制御し、セキュリティを向上させます。さらに、RDS Data APIは完全に管理されており、サーバーレスなため、どのようなトラフィック量にも自動的にスケーリングできます。RDS Data APIを使用することで、AWS Lambda関数、AWS AppSync GraphQL API、またはREST APIを呼び出すことができる任意のHTTPクライアントから、RDSデータベースのデータを簡単にアクセスおよび変更することができます。

RDS Data API のユースケース

以下は、RDS Data APIの主なユースケースです。

  • サーバーレスアプリケーション
    RDS Data APIは、データベース接続や認証情報の管理が不要であるため、サーバーレスアプリケーションに最適です。これにより、アプリケーションのコードがシンプルになり、メンテナンスが容易になります。

  • マイクロサービス
    RDS Data APIを使用して、RDSデータベースにアクセスするマイクロサービスを構築できます。これにより、大量のトラフィックを処理できるスケーラブルなアプリケーションを構築および維持できます。

  • モバイルおよび Web アプリケーション
    RDS Data APIを使用することで、モバイルおよびWebアプリケーションから安全にRDSデータベースにアクセスし、データを変更できます。これにより、複雑なデータ操作を処理できる効率的で応答性の高いアプリケーションを構築できます。

  • データ分析およびレポート
    RDS Data APIを使用することで、データ分析およびレポートのためにRDSデータベースにアクセスできます。これにより、データに基づいた洞察を生成し、情報を基にした意思決定ができます。

  • リアルタイムデータ処理
    RDS Data APIを使用することで、RDSデータベースからリアルタイムデータを処理できます。これは、リアルタイムのデータ処理と分析を必要とするアプリケーションに役立ちます。

How to Use RDS Data API

以下は、Boto3(Python向けのAWS SDK)を使用してRDS Data APIを使用する方法です。

  1. インストール
    RDS Data APIをBoto3と一緒に使用するには、コマンドプロンプトまたはターミナルでpip install boto3コマンドを実行して、Boto3ライブラリをインストールする必要があります。

  2. IAM権限
    IAMロールに必要な権限があることを確認する必要があります。必要な権限を持つIAMポリシーを作成し、IAMロールにアタッチすることができます。

  3. データベース接続
    RDSデータベースに接続する必要があります。これを行うには、Boto3のrdsdataserviceクライアントからconnect_to_databaseメソッドを使用できます。

python
import boto3

rds_data = boto3.client('rds-data')

response = rds_data.execute_statement(
    database='my_database',
    resourceArn='arn:aws:rds:us-east-1:123456789012:db:my_database',
    secretArn='arn:aws:secretsmanager:us-east-1:123456789012:secret:my_secret',
    sql='SELECT * FROM my_table'
)

print(response)

この例のコードは、my_databaseというデータベースに接続し、my_tableというテーブルでSELECT文を実行し、応答を表示します。

  1. CRUD操作
    RDS Data APIをBoto3で使用して、RDSデータベースでCRUD(作成、読み取り、更新、削除)操作を実行することができます。以下は、これらの操作を実行するためにRDS Data APIをBoto3で使用する方法の例です。
  • SELECT
python
response = rds_data.execute_statement(
    database='my_database',
    resourceArn='arn:aws:rds:us-east-1:123456789012:db:my_database',
    secretArn='arn:aws:secretsmanager:us-east-1:123456789012:secret:my_secret',
    sql='SELECT * FROM my_table'
)

print(response)
  • INSERT
python
response = rds_data.execute_statement(
    database='my_database',
    resourceArn='arn:aws:rds:us-east-1:123456789012:db:my_database',
    secretArn='arn:aws:secretsmanager:us-east-1:123456789012:secret:my_secret',
    sql='INSERT INTO my_table (column1, column2) VALUES (:value1, :value2)',
    parameters=[
        {'name': 'value1', 'value': {'stringValue': 'abc'}},
        {'name': 'value2', 'value': {'stringValue': 'def'}}
    ]
)

print(response)
  • UPDATE
python
response = rds_data.execute_statement(
    database='my_database',
    resourceArn='arn:aws:rds:us-east-1:123456789012:db:my_database',
    secretArn='arn:aws:secretsmanager:us-east-1:123456789012:secret:my_secret',
    sql='UPDATE my_table SET column1 = :value1 WHERE column2 = :value2',
    parameters=[
        {'name': 'value1', 'value': {'stringValue': 'xyz'}},
        {'name': 'value2', 'value': {'stringValue': 'def'}}
    ]
)

print(response)
  • DELETE
python
response = rds_data.execute_statement(
    database='my_database',
    resourceArn='arn:aws:rds:us-east-1:123456789012:db:my_database',
    secretArn='arn:aws:secretsmanager:us-east-1:123456789012:secret:my_secret',
    sql='DELETE FROM my_table WHERE column1 = :value1',
    parameters=[
      {'name': 'value1', 'value': {'stringValue': 'abc'}}
    ]
)

print(response)

これらの例では、execute_statementメソッドがRDSデータベースに対してSQL文を実行するために使用されています。databaseパラメータはデータベースの名前を指定し、resourceArnパラメータはRDSデータベースのAmazonリソース名(ARN)を指定し、secretArnパラメータはデータベースの資格情報を含むSecrets ManagerシークレットのARNを指定します。sqlパラメータは実行するSQL文を指定し、parametersパラメータはSQL文で使用されるパラメータ値を指定します。

トランザクション

RDS Data APIをBoto3とともに使用することで、Amazon RDSデータベースに対してトランザクションを実行することができます。トランザクションは、複数のSQL文を単一のユニットにグループ化し、アトミックに実行できる強力な機能です。以下は、RDS Data APIをBoto3で使用してトランザクションを実行する方法です。

  1. データベースに接続する
    まず、Boto3のrdsdataserviceクライアントのconnect_to_databaseメソッドを使用して、RDSデータベースに接続します。
python
import boto3

rds_data = boto3.client('rds-data')

response = rds_data.begin_transaction(
    database='my_database',
    resourceArn='arn:aws:rds:us-east-1:123456789012:db:my_database',
    secretArn='arn:aws:secretsmanager:us-east-1:123456789012:secret:my_secret'
)

transaction_id = response['transactionId']

print('Transaction ID:', transaction_id)

このコードは、my_databaseというデータベースに接続し、トランザクションを開始します。begin_transactionメソッドは、トランザクション内でSQLステートメントを実行するために使用されるトランザクションIDを含む応答を返します。

  1. SQLステートメントを実行する
    トランザクションが開始されたら、rdsdataserviceクライアントのexecute_statementメソッドを使用してSQLステートメントを実行できます。
python
response = rds_data.execute_statement(
    database='my_database',
    resourceArn='arn:aws:rds:us-east-1:123456789012:db:my_database',
    secretArn='arn:aws:secretsmanager:us-east-1:123456789012:secret:my_secret',
    sql='INSERT INTO my_table (column1, column2) VALUES (:value1, :value2)',
    parameters=[
        {'name': 'value1', 'value': {'stringValue': 'abc'}},
        {'name': 'value2', 'value': {'stringValue': 'def'}}
    ],
    transactionId=transaction_id
)

print(response)

この例では、トランザクション内でINSERTステートメントを実行するためにexecute_statementメソッドが使用されています。transactionIdパラメータは、SQLステートメントが実行されるトランザクションのIDを指定します。

  1. トランザクションをコミットまたはロールバックする
    SQLステートメントがトランザクション内で実行されたら、commit_transactionメソッドを使用してトランザクションをコミットするか、rollback_transactionメソッドを使用してトランザクションをロールバックすることができます。
python
response = rds_data.commit_transaction(
    resourceArn='arn:aws:rds:us-east-1:123456789012:db:my_database',
    secretArn='arn:aws:secretsmanager:us-east-1:123456789012:secret:my_secret',
    transactionId=transaction_id
)

print(response)

この例では、commit_transactionメソッドが使用されてトランザクションがコミットされます。

try-exceptブロック

Boto3を使ってRDS Data APIを使用する場合、try-exceptブロックを使用することで、コードがエラーにGracefullyに対処できるようになります。以下は、RDS Data APIをBoto3でtry-exceptブロック内で実行する方法の例です。

python
import boto3

rds_data = boto3.client('rds-data')

try:
    response = rds_data.begin_transaction(
        database='my_database',
        resourceArn='arn:aws:rds:us-east-1:123456789012:db:my_database',
        secretArn='arn:aws:secretsmanager:us-east-1:123456789012:secret:my_secret'
    )

    transaction_id = response['transactionId']

    response = rds_data.execute_statement(
        database='my_database',
        resourceArn='arn:aws:rds:us-east-1:123456789012:db:my_database',
        secretArn='arn:aws:secretsmanager:us-east-1:123456789012:secret:my_secret',
        sql='INSERT INTO my_table (column1, column2) VALUES (:value1, :value2)',
        parameters=[
            {'name': 'value1', 'value': {'stringValue': 'abc'}},
            {'name': 'value2', 'value': {'stringValue': 'def'}}
        ],
        transactionId=transaction_id
    )

    response = rds_data.commit_transaction(
        resourceArn='arn:aws:rds:us-east-1:123456789012:db:my_database',
        secretArn='arn:aws:secretsmanager:us-east-1:123456789012:secret:my_secret',
        transactionId=transaction_id
    )

    print(response)

except Exception as e:
    print(e)
    response = rds_data.rollback_transaction(
        resourceArn='arn:aws:rds:us-east-1:123456789012:db:my_database',
        secretArn='arn:aws:secretsmanager:us-east-1:123456789012:secret:my_secret',
        transactionId=transaction_id
    )

    print(response)

この例では、コードはmy_tableというテーブルにデータを挿入するトランザクションを実行しようとします。実行中に例外が発生した場合、コードはrollback_transactionメソッドを使用してトランザクションをロールバックします。

RDS Data APIにおけるパラメータ

RDS Data APIにおけるパラメータは、SQLステートメントに入力値を渡すために使用され、クエリの実行を容易にし、SQLインジェクションの脆弱性を回避するのに役立ちます。データAPIでは、データ型に応じて異なる形式で入力パラメータが必要です。文字列、整数、浮動小数点数、ブール値、null値、配列、JSONオブジェクトなど、さまざまなデータ型に対してパラメータを使用できます。

RDS Data APIを使用する場合、特定の形式でパラメータを提供する必要があります。以下は、RDS Data APIでパラメータを使用する手順です。

  1. パラメータ値のプレースホルダを含むSQLステートメントを定義します。プレースホルダには:parameter_nameの形式を使用し、例えばSELECT * FROM users WHERE age > :minimum_ageとなります。

  2. パラメータ値を含む辞書を作成します。キーはSQLステートメントのパラメータ名と一致している必要があり、値はデータ型に応じた必要な形式である必要があります。

{
  "minimum_age": {
    "longValue": 18
  }
}
  1. パラメータ辞書をExecuteStatementリクエストの一部として、RDS Data APIに渡します。
python
import boto3

client = boto3.client('rds-data')

response = client.execute_statement(
    secretArn='<your_secret_arn>',
    database='<your_database>',
    resourceArn='<your_resource_arn>',
    sql='SELECT * FROM users WHERE age > :minimum_age',
    parameters={
        "minimum_age": {
            "longValue": 18
        }
    }
)

ディクショナリをパラメータに変換

以下のクラスは、Pythonの辞書のリストをAWS Data APIのパラメータに渡す値に変換するものです。このクラスは、リスト内の各辞書に対して適切にフォーマットされたパラメータを生成します。

python
from typing import Any, Dict, List, Union

class DataAPIParameters:
    def __init__(self, dict_list: List[Dict[str, Any]]):
        """
        Initialize the DataAPIParameters class.
        """
        self.dict_list = dict_list

    def convert(
        self, dict_list: list[dict[str, Any]]
    ) -> list[list[dict[str, Union[str, dict[str, Any]]]]]:
        """
        Convert a list of dictionaries to the format required by AWS Data API parameters.
        """
        return [self.convert_dict_to_param(d) for d in dict_list]

    def convert_dict_to_param(
        self, d: dict[str, Any]
    ) -> list[dict[str, Union[str, dict[str, Any]]]]:
        """
        Convert a single dictionary to the format required by AWS Data API parameters.
        """
        return [
            {"name": k, "value": self.convert_value_to_param(v)} for k, v in d.items()
        ]

    def convert_dict_to_param(
        self, d: dict[str, Any]
    ) -> list[dict[str, Union[str, dict[str, Any]]]]:
        """
        Convert a single dictionary to the format required by AWS Data API parameters.
        """
        return [
            {"name": k, "value": self.convert_value_to_param(v)} for k, v in d.items()
        ]

    def convert_value_to_param(self, value: Any) -> Dict[str, Any]:
        """
        Convert a value to the format required by AWS Data API parameters.
        """
        if isinstance(value, str):
            return {'stringValue': value}
        elif isinstance(value, int):
            return {'longValue': value}
        elif isinstance(value, float):
            return {'doubleValue': value}
        elif isinstance(value, bool):
            return {'booleanValue': value}
        elif value is None:
            return {'isNull': True}
        elif isinstance(value, list) or isinstance(value, tuple):
            return {'arrayValue': {'values': [self.convert_value_to_param(v) for v in value]}}
        elif isinstance(value, dict):
            return {'stringValue': json.dumps(value)}
        else:
            raise TypeError(f'Unsupported data type: {type(value)}')

このコードは、入力として提供された辞書のリストを受け取り、AWS Data APIのparametersに適した形式に変換します。各データ型に基づいて適切な変換が行われます。

参考

https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds-data.html

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!