すべてのプロダクト
Search
ドキュメントセンター

Function Compute:RDS PostgreSQL へのアクセスのベストプラクティス

最終更新日:Sep 22, 2025

Function Compute では、状態は異なる実行環境インスタンス間で共有されません。データベースを使用して構造化データを永続化することで、状態の共有を実現できます。Function Compute を使用すると、クラウドデータベースにアクセスして、データクエリやデータ挿入などの操作を実行できます。このトピックでは、Python 3 を例として、同じ VPC 内または VPC とリージョンを跨いで ApsaraDB RDS for PostgreSQL にアクセスする方法について説明します。

開始する前に

  • RDS PostgreSQL インスタンスを作成する

  • このトピックのサンプルコード index.py のロジックは、users という名前のデータベーステーブルのすべてのデータをクエリすることです。実際の状況に合わせてテーブル名を変更し、テーブルに少なくとも 1 つのレコードがあることを確認してください。

手順

ステップ 1:データベースのホワイトリストを設定する

シナリオ 1:同じ VPC 内の PostgreSQL データベースにアクセスする

重要
  • 作成するデータベースインスタンスが、データベースインスタンスにアクセスする必要がある関数と同じリージョンにあることを確認してください。

  • Function Compute でサポートされているゾーンにデータベースインスタンスを作成します。詳細については、「Function Compute でサポートされているゾーン」をご参照ください。

  • データベースインスタンスが Function Compute でサポートされているゾーンにデプロイされていない場合は、VPC に vSwitch を作成します。 vSwitch は Function Compute と同じゾーンにある必要があります。さらに、Function Compute の指定されたサービスの VPC 構成で vSwitch ID を指定する必要があります。同じ VPC 内の異なる vSwitch は内部ネットワークを介して相互に通信できるため、Function Compute はこの vSwitch を介して VPC 内の他のゾーンのリソースにアクセスできます。具体的な手順については、「「vSwitch is in unsupported zone」エラーが発生した場合はどうすればよいですか?」をご参照ください。

  1. RDS インスタンスリスト にアクセスし、上部でリージョンを選択し、ターゲットインスタンス ID をクリックし、[基本情報] をクリックし、[VPC] の横にある [接続の詳細を表示] をクリックして、PostgreSQL の VPC 情報を表示します。

    image

  2. Function Compute コンソール にログインし、Python Web 関数を作成し、関数の VPC アクセスを有効にし、ターゲット VPC リソースを構成します。

    説明

    関数に構成された VPC が、データベースインスタンスにバインドされている VPC と同じであることを確認してください。

    image

  3. 関数の詳細ページで、[構成] > [ネットワーク] を選択し、[ネットワーク] ページで、関数構成の vSwitch の CIDR ブロックを取得します。

    image

  4. 前の手順で取得した vSwitch の CIDR ブロックをアクセスホワイトリストに追加します。

    重要

    IP アドレスホワイトリストを使用して、関数がデータベースにアクセスすることを承認します。セキュリティグループモードを使用しないでください。そうしないと、関数がデータベースに接続できない場合があり、ビジネスに影響します。

    1. RDS 管理コンソール にログインし、上部でリージョンを選択し、ターゲットインスタンス ID をクリックします。

    2. 左側のナビゲーションウィンドウで、[ホワイトリストとセキュリティグループ] を選択し、[ホワイトリスト設定] タブで、ターゲットホワイトリストテンプレート名を見つけ、右側の [変更] をクリックします。

    3. 表示される [ホワイトリストグループの変更] パネルで、[ホワイトリスト] 入力ボックスにターゲットインスタンスにバインドされている vSwitch の CIDR ブロックを入力し、[OK] をクリックします。

      image

構成が完了すると、関数はデータベースの内部ネットワークアドレスを介して PostgreSQL データベースにアクセスできます。

シナリオ 2:VPC またはリージョンを跨いで PostgreSQL データベースにアクセスする

異なる VPC とリージョンは、互いに完全に論理的に分離されています。通常の状況では、VPC とリージョンを跨いでデータベースにアクセスすることはできません。 VPC またはリージョンを跨いでデータベースにアクセスする必要がある場合は、関数に固定パブリック IP アドレスを構成できます。システムは、関数にバインドされている VPC にパブリック NAT ゲートウェイを作成し、パブリック IP アドレスを介してデータベースへのアクセスを許可します。

  1. RDS インスタンスリスト にアクセスし、上部でリージョンを選択し、ターゲットインスタンス ID をクリックし、[基本情報] をクリックし、[VPC] の横にある [接続の詳細を表示] をクリックして、PostgreSQL の VPC 情報を表示します。

    image

  2. Function Compute コンソール にログインし、Python Web 関数を作成し、関数の詳細ページで、[構成] > [ネットワーク] を選択し、[ネットワーク] パネルで、関数に固定パブリック IP アドレスを構成し、[デプロイ] をクリックします。

    image

  3. 表示される [固定パブリック IP 構成] ダイアログボックスで、プロンプトボックスをオンにし、[OK] をクリックします。構成が完了したら、[デフォルト NIC がインターネットにアクセスすることを許可する] パラメーターを [いいえ] に設定して、構成された固定パブリック IP アドレスを有効にします。詳細については、「固定パブリック IP アドレスを構成する」をご参照ください。

  4. 関数の詳細ページで、[構成] > [ネットワーク] を選択し、[ネットワーク] ページで、関数に構成された固定パブリック IP アドレスを取得します。

    image

  5. 前の手順で取得した固定パブリック IP アドレスをアクセスホワイトリストに追加します。

    重要

    IP アドレスホワイトリストを使用して、関数がデータベースにアクセスすることを承認します。セキュリティグループモードを使用しないでください。そうしないと、関数がデータベースに接続できない場合があり、ビジネスに影響します。

    1. RDS 管理コンソール にログインし、上部でリージョンを選択し、ターゲットインスタンス ID をクリックします。

    2. 左側のナビゲーションウィンドウで、[ホワイトリストとセキュリティグループ] を選択し、[ホワイトリスト設定] タブで、ターゲットホワイトリストテンプレート名を見つけ、右側の [変更] をクリックします。

    3. 表示される [ホワイトリストグループの変更] パネルで、[ホワイトリスト] 入力ボックスにバインドする固定パブリック IP アドレスを入力し、[OK] をクリックします。

      image

構成が完了すると、関数はデータベースのパブリックネットワークアドレスを介して PostgreSQL データベースにアクセスできます。

ステップ 2:関数で PostgreSQL データベースにアクセスする

  1. Function Compute コンソール にログインし、関数リストでターゲット関数を見つけ、関数の詳細ページで、[コード] タブをクリックし、データベーステーブルに従ってコードエディタに次のサンプルコードを記述します。

    from flask import Flask, jsonify
    import psycopg2  # psycopg2ライブラリを最初にインストールする必要があります
    import os
    import sys
    from datetime import datetime
    import logging
    
    
    app = Flask(__name__)
    
    # PostgreSQLシングルトン接続を格納するためのグローバル変数
    _postgresql_connection = None
    
    # データベース接続を作成する(シングルトンパターン)
    def getConnection():
        global _postgresql_connection
        try:
            # 接続が既に存在し、切断されていない場合は、それを直接返します
            if _postgresql_connection is not None:
                try:
                    # 接続が有効かどうかをテストします(簡単なコマンドテスト)
                    with _postgresql_connection.cursor() as cursor:
                        cursor.execute("SELECT 1")  # 接続状態をテストするための簡単なクエリ
                        result = cursor.fetchone()
                        if result and result[0] == 1:
                            return _postgresql_connection
                except psycopg2.OperationalError:
                    # 接続が切断されている場合は、リセットします
                    _postgresql_connection = None
    
            # 接続が存在しないか、切断されている場合は、再作成します
            _postgresql_connection = psycopg2.connect(
                database=os.environ['DATABASE'],
                user=os.environ['USER'],
                password=os.environ['PASSWORD'],
                host=os.environ['HOST'],
                port=os.environ['PORT'],
            )
            return _postgresql_connection
        except Exception as e:
            print(f"ERROR: 予期しないエラー:PostgreSQLインスタンスに接続できませんでした:{e}")
            raise
    
    
    @app.route('/', defaults={'path': ''})
    @app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
    def hello_world(path):
        conn = getConnection()
        try:
            with conn.cursor() as cursor:
                # usersテーブルのすべてのレコードをクエリします。usersテーブルは実際のテーブル名に応じて変更します
                sql = "SELECT * FROM users"
                cursor.execute(sql)
                result = cursor.fetchall()
                
                columns = [desc[0] for desc in cursor.description]  # フィールド名のリストを取得します
    
                # クエリ結果を辞書リストに変換します
                users = []
                for row in result:
                    user = {}
                    for idx, column_name in enumerate(columns):
                        value = row[idx]
                        if isinstance(value, datetime):  # 日付タイプのフィールドを処理します
                            user[column_name] = value.strftime('%Y-%m-%d %H:%M:%S')
                        else:
                            user[column_name] = value
                    users.append(user)
                    
                if users:
                    # すべてのユーザーのJSONレスポンスを返します
                    return jsonify(users), 200
                else:
                    # ユーザーが見つからない場合は、404エラーを返します
                    return jsonify({'error': 'ユーザーが見つかりません'}), 404
    
        except Exception as e:
            logging.error(f"データベース操作中にエラーが発生しました:{e}")
            return jsonify({'error': 'データベースエラー'}), 500
    
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=9000)
    
  2. 関数に必要な依存関係をインストールします:pip3 install -t . psycopg2 [コードのデプロイ] をクリックして、依存関係を有効にします。詳細な手順については、「コンソール Web IDE ターミナルを介して依存関係をインストールする」をご参照ください。

  3. [関数の詳細] ページで、[構成] > [環境変数] を選択し、[編集] をクリックし、[環境変数] パネルで次の環境変数を構成します。

    環境変数名

    環境変数値

    説明

    HOST

    pgm-*****q.pg.rds.aliyuncs.com

    データベースインスタンスのアクセスアドレス。 同じ VPC 内の PostgreSQL データベース シナリオを選択した場合は、この環境変数値をデータベースの内部ネットワークアドレスに設定します。 VPC またはリージョンを跨いで PostgreSQL データベースにアクセスする シナリオを選択した場合は、この環境変数値をデータベースの外部ネットワークアドレスに設定します。

    インスタンスリスト にアクセスし、上部でリージョンを選択し、ターゲットインスタンス ID をクリックします。左側のナビゲーションウィンドウで、[データベース接続] をクリックし、[データベース接続] 情報エリアで、データベースに接続するための接続アドレス情報を取得します。

    PORT

    5432

    データベース内部ネットワークポート番号

    USER

    *****

    PostgreSQL インスタンスで作成されたアカウント名。

    PASSWORD

    *****

    データベースパスワード

    DATABASE

    *****

    インスタンスで作成されたデータベース名。

  4. 関数の詳細ページで、[コード] タブを選択し、[関数のテスト] をクリックし、正常に実行された後の戻り結果を表示します。

    image

詳細情報

  • RDS PostgreSQL データベースにアクセスするその他の例については、「Function Compute Python accessing PostgreSQL database」をご参照ください。

  • Function Compute に構成されている vSwitch 情報を表示する方法、および RDS MySQL データベースで Function Compute の vSwitch CIDR ブロックを許可する方法については、「ネットワークを構成する」と「PostgreSQL のホワイトリストを構成する」をそれぞれご参照ください。

  • データベースアクセスに失敗した場合は、問題の症状に基づいてトラブルシューティングを行う必要があります。詳細については、「データベースアクセス失敗の一般的な原因」をご参照ください。

  • Serverless Devs コマンドラインツールを使用して関数を作成し、ApsaraDB RDS for PostgreSQL データベースにアクセスする場合は、次の手順をご参照ください。

    ここをクリックして Serverless Devs の操作手順を表示する

    1. Serverless Devs と Docker をインストールし、キー情報を追加します。 具体的な操作については、「クイックスタート」をご参照ください。

    2. コードディレクトリ mycode を作成し、s.yaml ファイルとコードファイル app.py を準備します。 app.py のサンプルコードについては、「ステップ 2:関数で PostgreSQL データベースにアクセスする」で提供されているサンプルコードをご参照ください。 s.yaml ファイルの例は次のとおりです。

      次の s.yaml の例は、同じ VPC 内の SQL Server データベースにアクセスするシナリオに適用できます。 VPC とリージョンを跨いでデータベースにアクセスする必要がある場合は、「シナリオ 2:VPC またはリージョンを跨いで PostgreSQL データベースにアクセスする」をご参照ください。

      # ------------------------------------
      #   公式マニュアル:https://manual.serverless-devs.com/user-guide/aliyun/#fc3
      #   ヒント:https://manual.serverless-devs.com/user-guide/tips/
      #   ご質問がある場合は、DingTalkグループ 33947367 に参加してください。
      # ------------------------------------
      edition: 3.0.0
      name: hello-world-app
      access: "default"
      
      vars: # グローバル変数
        region: "cn-hangzhou"  # 同じ VPC 内の RDS データベースにアクセスするシナリオを選択した場合は、関数が RDS データベースと同じリージョンにデプロイされていることを確認してください
      
      resources:
        hello_world:
          component: fc3 
          actions:       
            pre-${regex('deploy|local')}: 
              - component: fc3 build 
          props:
            region: ${vars.region}              
            functionName: "start-python-PostgreSQL"
            runtime: custom.debian10
            description: 'hello world by serverless devs'
            timeout: 10
            memorySize: 512
            cpu: 0.5
            diskSize: 512
            code: ./code
            customRuntimeConfig:
              port: 9000
              command:
                - python3
                - app.py
            internetAccess: true
            vpcConfig:
              vpcId: vpc-bp1dxqii29fpkc8pw**** # データベースインスタンスが配置されている VPC ID
              securityGroupId: sg-bp12ly2ie92ixrfc**** # セキュリティグループ ID
              vSwitchIds: 
                 - vsw-bp1ty76ijntee9z83**** # この vSwitch の CIDR ブロックがデータベースインスタンスアクセスホワイトリストに構成されていることを確認してください
            environmentVariables:
              PYTHONPATH: /code/python
              PATH: /code/python/bin:/var/fc/lang/python3.10/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin
              HOST: rm-*****.sqlserver.rds.aliyuncs.com  # データベースエンドポイント
              USER: ******   # インスタンスで作成されたアカウント名
              PASSWORD: *****     # データベースパスワード
              DATABASE: *****     # インスタンスで作成されたデータベース名。
              PORT: "5432"        # データベースポート
      <p>コードのディレクトリ構造は次のとおりです。</p><code code-type="xCode" data-tag="codeblock" id="897e3230feqpp" outputclass="language-plaintext">├── code
      │ ├── app.py
      │ └── requirements.txt
      └── s.yaml

      コードのディレクトリ構造は以下のとおりです。

      ├── code
      │ ├── app.py
      │ └── requirements.txt
      └── s.yaml

      requirements.txt ファイルで指定された依存関係は以下に示されています。

      flask==2.2.5
      psycopg2==2.9.10
    3. 次のコマンドを実行して、プロジェクトをビルドします。

      sudo s build --use-docker
    4. 次のコマンドを実行して、プロジェクトをデプロイします。

      sudo s deploy -y
    5. 次のコマンドを実行して、関数を呼び出します。

      説明

      関数に構成されている vSwitch の CIDR ブロックがデータベースインスタンスアクセスホワイトリストに追加されていることを確認してください。具体的な操作については、「ステップ 4」をご参照ください。

      sudo s invoke -e "{}"