Erstellen einer externen Funktion auf AWS über die Weboberfläche

In diesem Dokument wird eine Möglichkeit zum Erstellen einer externen Funktion auf der Amazon Web Services (AWS)-Cloudplattform gezeigt, einschließlich:

  • Erstellen eines Remotedienstes (Lambda-Funktion auf AWS)

  • Erstellen eines Proxydienstes (auf Amazon API Gateway)

  • Erstellen einer API-Integration in Snowflake

  • Erstellen einer externen Funktion in Snowflake

  • Aufrufen von externen Funktionen

Diese Anleitung setzt voraus, dass Sie bereits mit der AWS-Administration vertraut sind. Die Anweisungen geben allgemeine Schritte an, die Sie ausführen müssen, es werden allerdings keine detaillierten Anweisungen für die Verwendung der AWS Management Console bereitgestellt, da sich die Details ändern können.

Unter diesem Thema:

Planen einer externen Funktion auf AWS

Voraussetzungen für das Erstellen einer externen Funktion auf AWS

Sie benötigen:

  • Ein Konto mit AWS, einschließlich Berechtigungen für:

    • AWS-Rollen über IAM (Identitäts- und Zugriffsverwaltung) erstellen

    • AWS-Lambda-Funktionen erstellen

    • API Gateway-Endpunkte erstellen

  • Ein Snowflake-Konto, in dem Sie über ACCOUNTADMIN-Berechtigungen oder eine Rolle mit der Berechtigung CREATE INTEGRATION verfügen.

In diesem Dokument wird davon ausgegangen, dass Sie ein erfahrener AWS-Administrator sind.

Arbeitsblatt

Wenn Sie Ihre externe Funktion erstellen, sollten Sie sich bestimmte Informationen, die Sie eingeben, notieren (z. B. die API Gateway-URL), damit Sie diese Informationen in nachfolgenden Schritten verwenden können. Das Arbeitsblatt unten hilft Ihnen, diese Informationen festzuhalten.

==============================================================================================
=========================================== Worksheet ========================================
==============================================================================================

------------------ Information about the Lambda Function (remote service) --------------------

AWS Account ID.............: _____________________________________________

Lambda Function Name.......: _____________________________________________


---------------------- Information about the API Gateway (proxy Service) ---------------------

New IAM Role Name..........: _____________________________________________

New IAM Role ARN...........: _____________________________________________

Snowflake VPC ID (optional): _____________________________________________

New API Name...............: _____________________________________________

API Gateway Resource Name..: _____________________________________________

Resource Invocation URL....: _____________________________________________

Method Request ARN.........: _____________________________________________


------------ Information about the API Integration and External Function ---------------------

API Integration Name.......: _____________________________________________

API_AWS_IAM_USER_ARN.......: _____________________________________________

API_AWS_EXTERNAL_ID........: _____________________________________________

External Function Name.....: _____________________________________________

Zusätzliche Ressourcen für die Erstellung externer Funktionen auf AWS (optional)

Wenn Sie bereit sind, einen eigenen Remotedienst für Ihre eigene externe Funktion zu erstellen, sollten Sie sich die Beispiele für Remotedienste auf Basis von Lambda-Funktionen ansehen unter:

Schritt 1: Remotedienst erstellen (Lambda-Funktion auf AWS)

Es gibt mehrere Möglichkeiten, einen Remotedienst zu erstellen. Dieser Abschnitt zeigt, wie Sie einen Remotedienst erstellen, der als Python-Funktion implementiert ist, die in AWS Lambda ausgeführt wird.

Diese externe Funktion ist synchron. Weitere Informationen zum Erstellen einer asynchronen externen Funktion finden Sie unter Erstellen einer asynchronen Funktion auf AWS.

Diese Beispielfunktion in Python-Sprache gibt lediglich die Eingaben zurück. Die Eingaben werden als SQL VARIANT-Wert zurückgegeben, der einen oder mehrere Werte enthalten kann.

Diese Funktion akzeptiert Daten in demselben Format (JSON), das von Snowflake gesendet und gelesen wird. (Weitere Informationen zu Datenformaten finden Sie unter Eingangs- und Ausgangsdatenformate von Remotediensten.)

Diese Python-Funktion empfängt zwei Parameter, event und context. Der Parameter event enthält viele Unterfelder, von denen eines body ist. „Body“ ist ein Wörterbuch, das einen Schlüssel mit dem Namen data enthält. Der entsprechende Wert für data ist eine Zeichenfolge, die die von Snowflake gesendeten Daten im JSON-Format enthält. Da AWS Lambda die von Snowflake gesendete HTTP-POST-Anforderung verarbeitet, den Body extrahiert und den Body innerhalb des Ereignisparameters übergibt, muss diese Beispielfunktion nicht die gesamte HTTP-POST-Anforderung parsen.

Nachdem diese Python-Funktion den Body als Zeichenfolge extrahiert hat, ruft die Funktion eine JSON-Bibliotheksfunktion auf, um die Zeichenfolge in eine Python-Datenstruktur zu konvertieren. Die Funktion extrahiert dann einzelne Zeilen aus dieser Datenstruktur, verarbeitet sie und gibt für jede einen Wert zurück.

Der JSON-Text für den typischen Rückgabewert einer AWS Lambda-Funktion sieht wie folgt aus:

{
"statusCode": <http_status_code>,
"body":
        {
            "data":
                  [
                      [ 0, <value> ],
                      [ 1, <value> ]
                      ...
                  ]
        }
}

Die Daten des Rückgabewerts stimmen mit dem zuvor für die Eingabedaten beschriebenen Format überein. Bei AWS besteht die Konvention für einen HTTP-kompatiblen Dienst darin, den Body in einem JSON-Objekt zurückzugeben, das auch den HTTP-Statuscode enthält.

Führen Sie die folgenden Schritte aus, um diese AWS Lambda-Funktion zu erstellen:

  1. Melden Sie sich bei der AWS Management Console an, falls Sie dies noch nicht getan haben.

  2. Notieren Sie sich Ihre AWS-Konto-ID auf dem obigen Arbeitsblatt im Feld „AWS Account ID“.

    Wenn Sie Ihre AWS-Konto-ID suchen müssen, befolgen Sie die AWS-Anleitung.

  3. Wählen Sie Lambda aus.

  4. Wählen Sie Create function aus.

  5. Geben Sie einen Funktionsnamen ein.

    Notieren Sie sich den Namen auf dem obigen Arbeitsblatt im Feld „Lambda Function Name“.

  6. Wählen Sie die zu verwendende Sprache aus. Wählen Sie in diesem Beispiel Python 3.7 aus.

  7. Wählen Sie eine Ausführungsrolle für diese Funktion aus, oder erstellen Sie diese.

    Wählen Sie die entsprechenden Optionen aus, normalerweise Create a new role with basic Lambda permissions zum Erstellen einer neuen Rolle mit grundlegenden Lambda-Berechtigungen.

    (Diese Rolle ist von der Rolle Ihres Cloudkontos und von Ihren Snowflake-Rollen getrennt.)

  8. Klicken Sie auf die Schaltfläche Create Function.

  9. Geben Sie auf der Registerkarte lambda_function den Code für die Funktion ein. Wenn Sie noch keine eigene Funktion geschrieben haben, können Sie den Standardfunktionscode durch den folgenden Code ersetzen, der die Eingabe wiedergibt. Sie können diesen Code später ersetzen oder aktualisieren, wenn Sie bereit sind, eine benutzerdefinierte Funktion zu erstellen.

    Dieser Beispielcode geht davon aus, dass Sie die Lambda-Proxyintegration verwenden, wie von Snowflake in der Anleitung zum Erstellen des API Gateway-Endpunkts empfohlen.

    Wenn Sie nichts in das Bearbeitungsfenster einfügen können, versuchen Sie einen Doppelklick auf dem Dateinamen der Funktion, um die Bearbeitung zu aktivieren.

    import json
    
    def lambda_handler(event, context):
    
        # 200 is the HTTP status code for "ok".
        status_code = 200
    
        # The return value will contain an array of arrays (one inner array per input row).
        array_of_rows_to_return = [ ]
    
        try:
            # From the input parameter named "event", get the body, which contains
            # the input rows.
            event_body = event["body"]
    
            # Convert the input from a JSON string into a JSON object.
            payload = json.loads(event_body)
            # This is basically an array of arrays. The inner array contains the
            # row number, and a value for each parameter passed to the function.
            rows = payload["data"]
    
            # For each input row in the JSON object...
            for row in rows:
                # Read the input row number (the output row number will be the same).
                row_number = row[0]
    
                # Read the first input parameter's value. For example, this can be a
                # numeric value or a string, or it can be a compound value such as
                # a JSON structure.
                input_value_1 = row[1]
    
                # Read the second input parameter's value.
                input_value_2 = row[2]
    
                # Compose the output based on the input. This simple example
                # merely echoes the input by collecting the values into an array that
                # will be treated as a single VARIANT value.
                output_value = ["Echoing inputs:", input_value_1, input_value_2]
    
                # Put the returned row number and the returned value into an array.
                row_to_return = [row_number, output_value]
    
                # ... and add that array to the main array.
                array_of_rows_to_return.append(row_to_return)
    
            json_compatible_string_to_return = json.dumps({"data" : array_of_rows_to_return})
    
        except Exception as err:
            # 400 implies some type of error.
            status_code = 400
            # Tell caller what this function could not handle.
            json_compatible_string_to_return = event_body
    
        # Return the return value and HTTP status code.
        return {
            'statusCode': status_code,
            'body': json_compatible_string_to_return
        }
    
  10. Klicken Sie auf die Schaltfläche Deploy, um die Funktion bereitzustellen.

  11. Optional, aber dringend empfohlen: Testen Sie Ihre Funktion.

    Verwenden Sie für die von Snowflake bereitgestellte Python-Beispielfunktion die folgenden Testdaten (ersetzen Sie alle Standarddaten durch die folgenden Daten):

    {
      "body":
        "{ \"data\": [ [ 0, 43, \"page\" ], [ 1, 42, \"life, the universe, and everything\" ] ] }"
    }
    

    Die Ausführungsergebnisse sollten ungefähr wie folgt aussehen:

    {
      "statusCode": 200,
      "body": "{\"data\": [[0, [\"Echoing inputs:\", 43, \"page\"]], [1, [\"Echoing inputs:\", 42, \"life, the universe, and everything\"]]]}"
    }
    

Wenn die vorherigen Aktionen erfolgreich waren, haben Sie jetzt eine AWS Lambda-Funktion, die Sie als Remotedienst für Ihre externe Funktion verwenden können.

Schritt 2: Proxydienst konfigurieren (Amazon API Gateway) und API-Integration erstellen (in Snowflake).

Das Konfigurieren des Amazon API Gateway als Proxydienst erfordert mehrere Schritte wie:

  • Erstellen einer neuen IAM-Rolle in Ihrem AWS-Konto

  • Erstellen und Konfigurieren eines Amazon API Gateway-Endpunkts

  • Sichern des Amazon API Gateway-Endpunkts

  • Erstellen eines API-Integrationsobjekts in Snowflake

  • Einrichten einer Vertrauensstellung zwischen Snowflake und der neuen IAM-Rolle

Die Schritte überlappen sich, da für die API-Integration Informationen vom API Gateway (ARN (Amazon Resource Name) der Rolle) benötigt werden und für das API Gateway Informationen von der API-Integration (API_AWS_EXTERNAL_ID und API_AWS_IAM_USER_ARN) benötigt werden.

Neue IAM-Rolle in Ihrem AWS-Konto erstellen

Damit sich Snowflake bei Ihrem AWS-Konto authentifizieren kann, muss einem Snowflake-eigenen IAM-Benutzer (Identitäts- und Zugriffsverwaltung) die Berechtigung erteilt werden, eine IAM-Rolle in Ihrem AWS-Konto zu übernehmen. Dazu muss eine Vertrauensstellung eingerichtet werden. Um die Vertrauensstellung einzurichten, müssen Sie eine IAM-Rolle in Ihrem AWS-Konto erstellen und mit dem ARN des Snowflake-eigenen IAM-Benutzers konfigurieren. Außerdem müssen Sie in Snowflake ein API-Integrationsobjekt erstellen und das API-Integrationsobjekt mit den Informationen darüber konfigurieren, welche IAM-Rolle übernommen werden soll.

  1. Erstellen Sie eine neue IAM-Rolle.

  2. Wenn Sie aufgefordert werden, den Typ der vertrauenswürdigen Entität auszuwählen, wählen Sie Another AWS account aus.

  3. Wenn die Aufforderung Specify accounts that can use this role angezeigt wird, fügen Sie den Wert aus dem Feld „AWS-Konto-ID“ des Arbeitsblatts ein.

  4. Klicken Sie auf Next: Permissions.

  5. Legen Sie bei Bedarf Berechtigungen fest (Attach permissions policies).

  6. Geben Sie einen Rollennamen ein.

    • Notieren Sie sich den Rollennamen auf dem Arbeitsblatt im Feld „New IAM Role Name“.

  7. Klicken Sie auf die Schaltfläche Create role. Nachdem Sie die Rolle erstellt haben:

    • Notieren Sie sich den Role ARN auf dem Arbeitsblatt im Feld „New IAM Role ARN“.

API im Amazon-API-Gateway erstellen und konfigurieren

Wählen Sie Ihren Endpunkttyp: Regionaler Endpunkt vs. Privater Endpunkt

Sie greifen auf einen Proxydienst (wie das Amazon API Gateway) über eine URI zu, manchmal auch als „Endpunkt“ bezeichnet. Für Ihr Amazonas API Gateway können Sie beides erstellen:

  • Einen regionalen Endpunkt

  • Einen privaten Endpunkt

Auf einen regionalen Endpunkt kann über Regionen oder sogar über Clouds hinweg zugegriffen werden. Ihre Snowflake-Instanz, Ihr Proxydienst und Ihr Remotedienst können sich alle in verschiedenen Regionen oder sogar auf verschiedenen Cloudplattformen befinden. Beispielsweise könnte eine Snowflake-Instanz, die auf Azure ausgeführt wird, Anfragen an einen regionalen Amazon API Gateway-Endpunkt senden, der seinerseits Daten an einen Remotedienst weiterleiten könnte, der auf GCP ausgeführt wird.

Ein privater Endpunkt kann so konfiguriert werden, dass der Zugriff nur von einer Snowflake VPC (Virtual Private Cloud) in der gleichen AWS-Region über PrivateLink möglich ist.

Weitere Einzelheiten zu den Typen von Endpunkten auf AWS finden Sie unter:

Wenn Sie einen privaten Endpunkt verwenden möchten und sich nicht sicher sind, welche Region Sie verwenden, können Sie Ihre Region feststellen, indem Sie einen der folgenden Aktionen ausführen:

  • Rufen Sie die SQL-Funktion CURRENT_REGION() auf (z. B. SELECT CURRENT_REGION()).

  • Überprüfen Sie den Hostnamen Ihres Snowflake-Kontos, der normalerweise den Cloudanbieter und die Region angibt. Weitere Informationen zu Hostnamen von Konten, Regionen und Cloudanbieter finden Sie unter Unterstützte Cloudregionen.

Um einen privaten Endpunkt verwenden zu können, muss Ihr Konto die folgenden Anforderungen erfüllen:

  • Business Critical Edition (oder höhere) von Snowflake.

Auf AWS unterstützt Snowflake die Verbindung von Snowflake-Konten mit AWS VPCs. Private Endpunkte ermöglichen die Kommunikation zwischen VPCs (Virtuelle Private Clouds) über PrivateLink. Weitere Informationen zu Snowflake und AWS PrivateLink finden Sie unter

API Gateway-Endpunkt erstellen

Bevor Sie Ihr API Gateway erstellen und konfigurieren, wählen Sie, ob Sie einen regionalen Endpunkt oder einen privaten Endpunkt verwenden möchten. Weitere Informationen dazu finden Sie unter Wählen Sie Ihren Endpunkttyp: Regionaler Endpunkt vs. Privater Endpunkt.

Bemerkung

Sie können eine externe Funktion auch für Snowflake-Instanzen erstellen, die nicht auf AWS gehostet werden. Wenn sich Ihr virtuelles Warehouse auf Azure oder GCP (Google Cloud Platform) befindet, können Sie eine externe Funktion erstellen, die über ein Amazon API Gateway auf einen Remotedienst zugreift.

Die Schritte zum Erstellen eines API Gateway-Endpunkts sind unten aufgeführt:

  1. Wenn Sie planen, einen privaten Endpunkt zu verwenden, dann führen Sie folgenden Befehl über die Snowflake-Weboberfläche aus, um die VPC (Virtual Private Cloud)-ID zu erhalten:

    select system$get_snowflake_platform_info();
    

    Die Ausgabe sollte ungefähr wir folgt aussehen:

    {"snowflake-vpc-id":["vpc-12345678"]}
    

    Notieren Sie sich die VPC-ID (z. B. „vpc-12345678“) auf dem Arbeitsblatt im Feld „Snowflake VPC ID“.

    (Hinweis: Sie müssen eine VPC-ID verwenden, keine VPC-Endpunkt-ID. VPC-Endpunkt-IDs können sich im Verlauf der Zeit ändern).

  2. Wählen Sie auf der AWS Management Console die Option API Gateway aus.

  3. Wählen Sie Create API aus.

  4. Wählen Sie den Typ des Endpunkts (regional oder privat) aus.

    • Wenn Sie einen regionalen Endpunkt verwenden möchten:

      • Suchen Sie nach REST API, und klicken Sie auf die Schaltfläche Build.

    • Wenn Sie einen privaten Endpunkt verwenden möchten:

      • Suchen Sie nach REST API private, und klicken Sie auf die Schaltfläche Build.

    Wichtig

    Stellen Sie sicher, dass Sie REST API oder REST API private auswählen. Wählen Sie nicht HTTP API oder eine andere Option aus.

  5. Wählen Sie die Option New API aus.

  6. Geben Sie einen Namen für die neue API ein.

    Notieren Sie sich den Namen auf dem Arbeitsblatt im Feld „New API Name“.

  7. Wenn Sie aufgefordert werden, einen Endpoint Type auszuwählen, wählen Sie entweder Regional oder Private aus.

  8. Wenn Sie einen privaten Endpunkt erstellen, geben Sie die Snowflake-VPC-ID ein, die Sie sich auf dem Arbeitsblatt im Feld „Snowflake VPC ID“ notiert haben.

    (Wenn Sie keinen privaten Endpunkt erstellen, brauchen Sie keine VPC-ID einzugeben).

  9. Klicken Sie auf die Schaltfläche Create API.

    Dies sollte Sie zu einem neuen Bildschirm führen, in dem Sie Ressourcen erstellen können.

  10. Erstellen Sie eine Ressource.

    (Möglicherweise müssen Sie auf die Schaltfläche Actions klicken, um die Option Create Resource anzuzeigen).

    Notieren Sie sich den Ressourcennamen auf dem Arbeitsblatt im Feld „API Gateway Resource Name“.

    Nachdem Sie auf die Schaltfläche Create Resource geklickt haben, sollte auf dem Bildschirm Folgendes angezeigt werden: No methods defined for the resource.

  11. Erstellen Sie eine neue Methode. Klicken Sie auf Actions, und wählen Sie Create Method für diese Ressource aus.

    Geben Sie die Option POST an. (Wenn die Option POST nicht angezeigt wird, klicken Sie auf das kleine Dropdown-Menüfeld unter dem Ressourcennamen).

    Dies sollte einen neuen Fensterbereich anzeigen, der Integration type und andere Optionen anzeigt.

  12. Der Integration type sollte Lambda Function sein. Wenn dieser nicht bereits ausgewählt ist, wählen Sie ihn aus.

  13. Aktivieren Sie das Kontrollkästchen Use Lambda Proxy integration.

    Es ist wichtig, Lambda-Proxyintegration auszuwählen, da sich JSON ohne Lambda-Proxyintegration von JSON mit Lambda-Proxyintegration unterscheidet. Weitere Informationen zur Lambda-Proxyintegration finden Sie in der AWS-Dokumentation unter:

  14. Fügen Sie in das Feld Lambda Function den Lambda-Funktionsnamen ein, den Sie sich auf dem Arbeitsblatt notiert haben.

  15. Speichern Sie die Eingaben.

  16. Klicken Sie auf die Schaltfläche Actions, und wählen Sie die Aktion Deploy API aus.

  17. Wählen Sie einen Stagingbereich für diese Funktion aus, oder erstellen Sie einen.

  18. Unter dem Ressourcennamen sollte POST angezeigt sein.

    Wenn dies nicht angezeigt wird, müssen Sie möglicherweise den Ressourcenstrukturbaum erweitern, indem Sie auf das Dreieck links neben dem Ressourcennamen klicken.

  19. Klicken Sie auf POST, und notieren Sie sich dann die Invoke URL für die POST-Anforderung im Feld „Resource Invocation URL“ auf dem Arbeitsblatt.

    Stellen Sie sicher, dass die Aufruf-URL den Namen der Ressource enthält. Ist dies nicht der Fall, haben Sie möglicherweise auf die Aufruf-URL für den Stagingbereich und nicht auf die Ressource geklickt.

  20. Klicken Sie auf Save Changes.

Amazon API Gateway-Endpunkt sichern

Eine Übersicht zum Sichern von Proxydienst-Endpunkten wie Amazon API Gateway-Endpunkten finden Sie unter Proxydienst sichern.

So sichern Sie einen Amazon API Gateway-Endpunkt:

  1. An diesem Punkt sollten Sie sich auf dem Bildschirm befinden, der Ihre API Gateway-Informationen anzeigt, und Sie sollten Ihre Ressource und die POST-Methode sehen.

    Wenn Sie sich noch nicht dort befinden, gehen Sie wie folgt vor:

    1. Wechseln Sie in der AWS Management Console auf die Seite „API Gateway“.

    2. Wählen Sie Ihr API Gateway aus, wenn Sie dies nicht bereits getan haben.

    3. Klicken Sie im linken Fensterbereich auf Resources.

    4. Klicken Sie auf das Feld POST. (Wenn das Feld nicht angezeigt wird, erweitern Sie den Ressourcenstrukturbaum, indem Sie im Resources-Fensterbereich, der normalerweise der zweite Fensterbereich von links ist, auf das Dreieck links neben der Ressource klicken).

  2. Kopieren Sie den Method Request ARN aus dem Feld Method Request in das Feld „Method Request ARN“ des Arbeitsblatts.

  3. Klicken Sie auf den Titel Method Request.

  4. Geben Sie an, dass die Method Request eine AWS_IAM-Autorisierung erfordert.

    Beachten Sie, dass Sie nach der Auswahl der AWS_IAM-Autorisierung im Dropdownmenü auf das kleine Häkchen neben dem Menü klicken müssen, um Ihre Wahl zu bestätigen.

  5. Legen Sie die Ressourcenrichtlinie für das API Gateway fest, um anzugeben, wer zum Aufrufen des Gateway-Endpunkts berechtigt ist.

    Um das Bearbeitungsfenster zu erreichen, in dem Sie eine Ressourcenrichtlinie eingeben können, müssen Sie eventuell in der linken Spalte des Fensters auf Resource Policy für die API klicken.

    • Regionaler Endpunkt:

      Fügen Sie die unten stehende JSON-formatierte Ressourcenrichtlinienvorlage in den Ressourcenrichtlinien-Editor ein, und ersetzen Sie dann die Platzhalter durch die entsprechenden Werte vom Arbeitsblatt, wie unten beschrieben.

      {
          "Version": "2012-10-17",
          "Statement":
          [
              {
              "Effect": "Allow",
              "Principal":
                  {
                  "AWS": "arn:aws:sts::<12-digit-number>:assumed-role/<external_function_role>/snowflake"
                  },
              "Action": "execute-api:Invoke",
              "Resource": "<method_request_ARN>"
              }
          ]
      }
      

      Ersetzen Sie die folgenden Teile der Ressourcenrichtlinie:

      • Ersetzen Sie die <12-stellige Zahl> durch die AWS-Konto-ID, die Sie auf dem Arbeitsblatt notiert haben.

      • Ersetzen Sie <Rolle_für_externe_Funktion> durch den Rollennamen aus dem Feld „New IAM Role Name“ des Arbeitsblatts.

        Wenn Ihr AWS-Rollenname wie folgt ist:

        arn:aws:iam::987654321098:role/MyNewIAMRole
        

        dann sollte das Ergebnis wie folgt sein:

        "AWS": "arn:aws:sts::987654321098:assumed-role/MyNewIAMRole/snowflake"
        
      • Ersetzen Sie den <Methodanforderungs-ARN> durch den Wert im Feld „Method Request ARN“ des Arbeitsblatts. Dies ist der ARN der POST-Methode der Ressource.

        Bemerkung

        Durch Festlegen der Ressource auf den Methodenanforderungs-ARN wird angegeben, dass das API Gateway nur Aufrufe der angegebenen Ressource zulassen soll. Es ist möglich, eine Teilmenge des Methodenanforderungs-ARN als Präfix anzugeben, sodass mehrere Ressourcen desselben API-Gateway aufgerufen werden können.

        Wenn beispielsweise der Methodenanforderungs-ARN wie folgt lautet:

        arn:aws:execute-api:us-west-1:123456789012:a1b2c3d4e5/*/POST/MyResource
        

        dann können Sie nur das folgende Präfix angeben:

        arn:aws:execute-api:us-west-1:123456789012:a1b2c3d4e5/*/
        
    • Privater Endpunkt:

      Fügen Sie die unten stehende Ressourcenrichtlinienvorlage in den Ressourcenrichtlinien-Editor ein, und ersetzen Sie dann die Platzhalter durch die entsprechenden Werte vom Arbeitsblatt, wie unten beschrieben.

      {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Principal": {
                      "AWS": "arn:aws:sts::<12-digit-number>:assumed-role/<external_function_role>/snowflake"
                  },
                  "Action": "execute-api:Invoke",
                  "Resource": "<method_request_ARN>",
                  "Condition": {
                      "StringEquals": {
                          "aws:sourceVpc": "<VPC_ID>"
                      }
                  }
              }
          ]
      }
      

      Ersetzen Sie die folgenden Teile der Ressourcenrichtlinie:

      • Ersetzen Sie <12-digit-number>, <external_function_role> und <method_request_ARN> wie oben für einen regionalen Endpunkt beschrieben.

      • Ersetzen Sie den Wert im Feld <VPC_ID> durch die Snowflake-VPC-ID Ihrer Region, die Sie im Feld „Snowflake VPC ID“ des Arbeitsblatts notiert haben.

  6. Wenn Sie nicht bereits auf Save geklickt haben, um die Ressourcenrichtlinie zu speichern, tun Sie dies jetzt.

  7. Stellen Sie die aktualisierten API bereit.

In den nächsten Schritten erstellen Sie ein Snowflake-API-Integrationsobjekt. Schließen Sie jetzt nicht das AWS-Administrationsfenster. Sie müssen später zu diesem Fenster zurückkehren.

API-Integrationsobjekt in Snowflake erstellen

  1. Öffnen Sie (falls noch nicht geschehen) eine Snowflake-Sitzung, normalerweise eine Snowflake-Weboberflächensitzung.

  2. Verwenden Sie eine Snowflake-Rolle mit ACCOUNTADMIN-Berechtigungen oder mit der CREATE INTEGRATION-Berechtigung, zum Beispiel:

    use role has_accountadmin_privileges;
    
  3. Geben Sie den Befehl CREATE API INTEGRATION ein, um eine API-Integration zu erstellen. Der Befehl sollte ungefähr wie folgt aussehen:

    CREATE OR REPLACE API INTEGRATION my_api_integration_01
      api_provider = aws_api_gateway
      api_aws_role_arn = '<new_IAM_role_ARN>'
      api_allowed_prefixes = ('https://')
      enabled = true;
    

    Passen Sie den Befehl an:

    • Wenn Sie einen privaten Endpunkt verwenden, sollte die api_provider-Klausel auf den Wert aws_private_api_gateway festgelegt sein. Andernfalls sollte die api_provider-Klausel auf aws_api_gateway festgelegt werden.

    • Der <new_IAM_role_ARN> sollte der Wert im Feld „New IAM Role ARN“ des Arbeitsblatts sein.

    • Das Feld api_allowed_prefixes sollte die Ressourcenaufruf-URL enthalten, die Sie zuvor notiert haben.

    • Möglicherweise möchten Sie auch den Namen der API-Integration anpassen, anstatt den Wert aus dem Beispiel zu verwenden.

    Im Folgenden finden Sie ein Beispiel für eine vollständige CREATE API INTEGRATION-Anweisung:

    create or replace api integration demonstration_external_api_integration_01
        api_provider=aws_api_gateway
        api_aws_role_arn='arn:aws:iam::123456789012:role/my_cloud_account_role'
        api_allowed_prefixes=('https://xyz.execute-api.us-west-2.amazonaws.com/production/')
        enabled=true;
    
  4. Notieren Sie sich den Namen der erstellten API-Integration auf dem Arbeitsblatt unter „API Integration Name“. Sie benötigen den Namen der API-Integration, wenn Sie später den Befehl CREATE EXTERNAL FUNCTION ausführen.

  5. Führen Sie den oben eingegebenen CREATE API INTEGRATION-Befehl aus.

  6. Führen Sie den Befehl DESCRIBE INTEGRATION aus:

    DESCRIBE INTEGRATION <my_integration_name>;
    

    Beispiel:

    DESCRIBE INTEGRATION my_api_integration_01;
    
  7. Suchen Sie nach der Eigenschaft API_AWS_IAM_USER_ARN, und notieren Sie sich den Wert von property_value dieser Eigenschaft auf dem Arbeitsblatt.

  8. Suchen Sie nach der Eigenschaft API_AWS_EXTERNAL_ID, und notieren Sie sich den Wert von property_value dieser Eigenschaft auf dem Arbeitsblatt.

    Beachten Sie, dass der Wert von property_value von API_AWS_EXTERNAL_ID häufig mit einem Gleichheitszeichen („=“) endet. Das Gleichheitszeichen ist Teil des Wertes. Stellen Sie also sicher, dass Sie es zusammen mit dem Rest des „property_value“ ausschneiden und einfügen.

Für die nächsten Schritte kehren Sie zum AWS-Verwaltungsfenster zurück. Schließen Sie jetzt nicht das Snowflake-Verwaltungsfenster. Sie müssen später zu diesem Fenster zurückkehren.

Vertrauensstellungen zwischen Snowflake und der neuen IAM-Rolle einrichten

In der AWS Management Console:

  1. Wählen Sie IAM aus.

  2. Wählen Sie Roles aus.

  3. Suchen Sie im Arbeitsblatt den Wert im Feld „New IAM Role Name“, und suchen Sie dann in der AWS Management Console nach demselben Wert (Rollenname).

  4. Klicken Sie auf die Registerkarte Trust relationships und dann auf die Schaltfläche Edit trust relationship.

    Dadurch wird das Policy Document geöffnet, dem Sie Authentifizierungsinformationen hinzufügen können.

  5. Suchen Sie in Policy Document das Feld Statement.Principal.AWS, und ersetzen Sie den Wert (nicht den Schlüssel) durch den Wert im Feld „API_AWS_IAM_USER_ARN“ des Arbeitsblatts.

  6. Suchen Sie das Feld Statement.Condition. Anfangs sollte dies nur geschweifte Klammern („{}“) enthalten.

  7. Fügen Sie Folgendes zwischen die geschweiften Klammern ein: "StringEquals": { "sts:ExternalId": "xxx" }.

  8. Ersetzen Sie die xxx durch den Wert für das Feld „API_AWS_EXTERNAL_ID“ im Arbeitsblatt.

  9. Nachdem Sie das Policy Document für die Vertrauensstellung bearbeitet haben, sollte es wie folgt aussehen:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::1234567898012:user/development/development_user"
          },
          "Action": "sts:AssumeRole",
          "Condition": {"StringEquals": { "sts:ExternalId": "EXTERNAL_FUNCTIONS_SFCRole=3_8Hcmbi9halFOkt+MdilPi7rdgOv=" }}
        }
      ]
    }
    
  10. Klicken Sie auf Update Trust Policy.

Schritt 3: Externe Funktion erstellen

Gehen Sie nun zurück zur Snowflake-Weboberfläche (wo Sie zuvor den Befehl CREATE API INTEGRATION eingegeben haben).

  1. Geben Sie den Befehl CREATE EXTERNAL FUNCTION ein. Dies sollte ungefähr wir folgt aussehen:

    CREATE EXTERNAL FUNCTION my_external_function(n INTEGER, v VARCHAR)
        RETURNS VARIANT
        API_INTEGRATION = <api_integration_name>
        AS '<resource_invocation_url>';
    

    Passen Sie den Befehl an:

    • Der Wert <api_integration_name> sollte den Namen der API-Integration enthalten, die Sie zuvor erstellt haben.

    • Der Wert für <resource_invocation_url> sollte die Ressourcenaufruf-URL sein, die Sie sich zuvor notiert haben. Stellen Sie sicher, dass diese URL nicht nur den Stagingbereichsnamen, sondern auch den API Gateway-Ressourcennamen enthält.

    • Möglicherweise möchten Sie auch den Funktionsnamen anpassen.

    In diesem Beispiel werden zwei Argumente übergeben (ein INTEGER und ein VARCHAR), da dies die Argumente sind, die die Lambda-Funktion erwartet. Wenn Sie Ihre eigene Lambda-Funktion erstellen, müssen Sie die entsprechenden Argumente für Ihre Lambda-Funktion übergeben.

  2. Notieren Sie sich auf dem Arbeitsblatt unter „External Function Name“ den Namen der erstellten externen Funktion.

  3. Wenn Sie den oben eingegebenen CREATE EXTERNAL FUNCTION-Befehl noch nicht ausgeführt haben, führen Sie ihn jetzt aus.

Schritt 4: Externe Funktion aufrufen

  1. Erteilen Sie gegebenenfalls einer oder mehreren Snowflake-Rollen die Berechtigung USAGE für die externe Funktion, damit diese Rollen die externe Funktion aufrufen können. (Eine Rolle muss über USAGE- oder OWNERSHIP-Berechtigung für diese externe Funktion verfügen.)

  2. Führen Sie Ihre Funktion aus, indem Sie Folgendes aufrufen:

    SELECT my_external_function(42, 'Adams');
    

    Wenn Sie den Funktionsnamen im Befehl CREATE EXTERNAL FUNCTION angepasst haben, dann ersetzen Sie „my_external_function“ durch den angepassten Namen.

    Der zurückgegebene Wert sollte wie folgt aussehen:

    [0, 42, "Adams"]
    

    wobei 42, "Adams" der zurückgegebene Wert und 0 die Zeilennummer des zurückgegebenen Wertes ist.

Erstellen einer asynchronen Funktion auf AWS (optional)

Um das Tutorial einfach zu halten, wird eine synchrone externe Beispielfunktion erstellt. Anspruchsvollere externe Funktionen können davon profitieren, wenn sie asynchron sind.

Dieser Abschnitt der Dokumentation enthält Informationen zum Erstellen einer asynchronen externen Funktion auf AWS. (Bevor Sie Ihre erste asynchrone externe Funktion implementieren, sollten Sie zunächst den Konzeptionellen Überblick zu asynchronen externen Funktionen lesen.)

Auf AWS müssen asynchrone Remotedienste die folgenden Einschränkungen überwinden:

  • Da es sich bei HTTP POST und GET um separate Anforderungen handelt, muss der Remotedienst Informationen über den von der POST-Anforderung gestarteten Workflow aufbewahren, damit der Status später von der GET-Anforderung abgefragt werden kann.

    Typischerweise ruft jeder HTTP POST und HTTP GET eine separate Instanz der Handlerfunktion(en) in einem separaten Prozess oder Thread auf. Die einzelnen Instanzen teilen sich den Speicher nicht. Damit der GET-Handler den Status oder die verarbeiteten Daten lesen kann, muss der GET-Handler auf eine gemeinsame Speicherressource zugreifen, die auf AWS verfügbar ist.

  • Die einzige Möglichkeit für den POST-Handler, den anfänglichen HTTP 202-Antwortcode zu senden, ist über eine return-Anweisung (oder eine gleichwertige Anweisung), die die Ausführung des Handlers beendet. Daher muss der POST-Handler vor der Rückgabe von HTTP 202 einen unabhängigen Prozess (oder Thread) starten, um die eigentliche Datenverarbeitung des Remotedienstes durchzuführen. Dieser unabhängige Prozess benötigt typischerweise Zugriff auf den Speicher, der für den GET-Handler sichtbar ist.

Um diese Einschränkung für einen asynchronen Remotedienst zu überwinden, können beispielsweise drei Prozesse (oder Threads) und ein gemeinsamer Speicher verwendet werden:

Illustration of processes for an Asynchronous Remote Service

Im folgenden Modell haben die Prozesse die folgenden Aufgaben:

  • Der HTTP-POST-Handler:

    • Liest die Eingangsdaten. Bei einer Lambda-Funktion wird der Textbereich des Eingabeparameters event der Handler-Funktion ausgelesen.

    • Liest die Batch-ID. Bei einer Lambda-Funktion wird die Kopfzeile des Eingabeparameters event gelesen.

    • Startet den Datenverarbeitungsprozess und übergibt ihm die Daten und die Batch-ID. Die Daten werden normalerweise beim Aufruf übergeben, sie können aber auch durch Schreiben in einen externen Speicher übergeben werden.

    • Erfasst die Batch-ID im gemeinsamen Speicher, auf den sowohl der Datenverarbeitungsprozess als auch der HTTP-GET-Handler-Prozess zugreifen können.

    • Erfasst bei Bedarf, dass die Verarbeitung dieser Batches noch nicht abgeschlossen ist.

    • Gibt HTTP 202 zurück, wenn kein Fehler erkannt wurde.

  • Der Datenverarbeitungscode:

    • Liest die Eingangsdaten.

    • Verarbeitet die Daten.

    • Stellt das Ergebnis für den GET-Handler zur Verfügung (entweder durch Schreiben der Ergebnisdaten in den gemeinsamen Speicher oder durch Bereitstellung einer API, über den die Ergebnisse abgefragt werden können).

    • Aktualisiert in der Regel den Status dieses Batches (z. B. von IN_PROGRESS in SUCCESS), um anzuzeigen, dass die Ergebnisse zum Lesen bereit sind.

    • Beendet den Prozess. Optional kann dieser Prozess einen Fehlerindikator zurückgeben. Snowflake sieht dies nicht direkt (Snowflake sieht nur den HTTP-Rückgabecode von POST-Handler und GET-Handler), aber die Rückgabe eines Fehlerindikators aus dem Datenverarbeitungsprozess könnte bei der Fehlersuche hilfreich sein.

  • Der GET-Handler:

    • Liest die Batch-ID. Bei einer Lambda-Funktion wird die Kopfzeile des Eingabeparameters event gelesen.

    • Liest den Speicher, um den aktuellen Status dieses Batches zu erhalten (z. B. IN_PROGRESS oder SUCCESS).

    • Wenn die Verarbeitung noch nicht abgeschlossen ist, dann wird 202 zurückgegeben.

    • Wenn die Verarbeitung erfolgreich abgeschlossen ist, dann:

      • Liest die Ergebnisse.

      • Bereinigt den Speicher.

      • Gibt die Ergebnisse zusammen mit HTTP-Code 200 zurück.

    • Wenn der gespeicherte Status einen Fehler anzeigt, dann:

      • Bereinigt den Speicher.

      • Gibt einen Fehlercode zurück.

    Beachten Sie, dass der GET-Handler für einen Batch möglicherweise mehrfach aufgerufen wird, wenn die Verarbeitung so lange dauert, dass mehrere HTTP-GET-Anforderungen gesendet werden.

Von diesem Modell gibt es viele mögliche Varianten. Beispiel:

  • Die Batch-ID und der Status könnten am Anfang des Datenverarbeitungsprozesses geschrieben werden und nicht am Ende des POST-Prozesses.

  • Die Datenverarbeitung kann in einer separaten Funktion (z. B. einer separaten Lambda-Funktion) oder sogar als komplett separater Dienst erfolgen.

  • Der Datenverarbeitungscode muss nicht unbedingt in den gemeinsamen Speicher schreiben. Stattdessen können die verarbeiteten Daten auf andere Weise zur Verfügung gestellt werden. Eine API kann z. B. die Batch-ID als Parameter annehmen und die Daten zurückgeben.

Der Implementierungscode sollte die Möglichkeit in Betracht ziehen, dass die Verarbeitung zu lange dauert oder fehlschlägt, und daher müssen alle Teilergebnisse bereinigt werden, um nicht unnötig Speicherplatz zu verbrauchen.

Der Speichermechanismus muss über mehrere Prozesse (oder Threads) hinweg gemeinsam genutzt werden können. Mögliche Speichermechanismen sind:

  • Von AWS bereitgestellte Speichermechanismen, wie z. B.:

  • Speicher, der sich außerhalb von AWS befindet, aber von AWS aus zugänglich ist.

Der Code für jeden der obigen drei Prozesse kann als separate Lambda-Funktion geschrieben werden (eine für den POST-Handler, eine für die Datenverarbeitungsfunktion und eine für den GET-Handler), oder als eine einzige Funktion, die auf verschiedene Weise aufgerufen werden kann.

Der folgende Python-Beispielcode ist eine einzelne Lambda-Funktion, die separat für den POST-, den Datenverarbeitungs- und den GET-Prozess aufgerufen werden kann.

Dieser Code zeigt eine Beispielabfrage mit Ausgabe. Der Fokus in diesem Beispiel liegt auf den drei Prozessen und wie sie interagieren, nicht auf dem gemeinsamen Speichermechanismus (DynamoDB) oder die Datentransformation (Standpunktanalyse). Der Code ist so strukturiert, dass es einfach ist, den Beispielspeichermechanismus und die Datentransformation durch andere zu ersetzen.

Der Einfachheit halber folgendes Beispiel:

  • Einige wichtige Werte (z. B. die AWS-Region) werden hart kodiert.

  • Setzt das Vorhandensein einiger Ressourcen voraus (z. B. die Tabelle „Jobs“ in Dynamo).

import json
import time
import boto3

HTTP_METHOD_STRING = "httpMethod"
HEADERS_STRING = "headers"
BATCH_ID_STRING = "sf-external-function-query-batch-id"
DATA_STRING = "data"
REGION_NAME = "us-east-2"

TABLE_NAME = "Jobs"
IN_PROGRESS_STATUS = "IN_PROGRESS"
SUCCESS_STATUS = "SUCCESS"

def lambda_handler(event, context):
    # this is called from either the GET or POST
    if (HTTP_METHOD_STRING in event):
        method = event[HTTP_METHOD_STRING]
        if method == "POST":
            return initiate(event, context)
        elif method == "GET":
            return poll(event, context)
        else:
            return create_response(400, "Function called from invalid method")

    # if not called from GET or POST, then this lambda was called to
    # process data
    else:
        return process_data(event, context)


# Reads batch_ID and data from the request, marks the batch_ID as being processed, and
# starts the processing service.
def initiate(event, context):
    batch_id = event[HEADERS_STRING][BATCH_ID_STRING]
    data = json.loads(event["body"])[DATA_STRING]

    lambda_name = context.function_name

    write_to_storage(batch_id, IN_PROGRESS_STATUS, "NULL")
    lambda_response = invoke_process_lambda(batch_id, data, lambda_name)

    # lambda response returns 202, because we are invoking it with
    # InvocationType = 'Event'
    if lambda_response["StatusCode"] != 202:
        response = create_response(400, "Error in inititate: processing lambda not started")
    else:
        response = {
            'statusCode': lambda_response["StatusCode"]
        }

    return response


# Processes the data passed to it from the POST handler. In this example,
# the processing is to perform sentiment analysis on text.
def process_data(event, context):
    data = event[DATA_STRING]
    batch_id = event[BATCH_ID_STRING]

    def process_data_impl(data):
        comprehend = boto3.client(service_name='comprehend', region_name=REGION_NAME)
        # create return rows
        ret = []
        for i in range(len(data)):
            text = data[i][1]
            sentiment_response = comprehend.detect_sentiment(Text=text, LanguageCode='en')
            sentiment_score = json.dumps(sentiment_response['SentimentScore'])
            ret.append([i, sentiment_score])
        return ret

    processed_data = process_data_impl(data)
    write_to_storage(batch_id, SUCCESS_STATUS, processed_data)

    return create_response(200, "No errors in process")


# Repeatedly checks on the status of the batch_ID, and returns the result after the
# processing has been completed.
def poll(event, context):
    batch_id = event[HEADERS_STRING][BATCH_ID_STRING]
    processed_data = read_data_from_storage(batch_id)

    def parse_processed_data(response):
        # in this case, the response is the response from DynamoDB
        response_metadata = response['ResponseMetadata']
        status_code = response_metadata['HTTPStatusCode']

        # Take action depending on item status
        item = response['Item']
        job_status = item['status']
        if job_status == SUCCESS_STATUS:
            # the row number is stored at index 0 as a Decimal object,
            # we need to convert it into a normal int to be serialized to JSON
            data = [[int(row[0]), row[1]] for row in item['data']]
            return {
                'statusCode': 200,
                'body': json.dumps({
                    'data': data
                })
            }
        elif job_status == IN_PROGRESS_STATUS:
            return {
                'statusCode': 202,
                "body": "{}"
            }
        else:
            return create_response(500, "Error in poll: Unknown item status.")

    return parse_processed_data(processed_data)


def create_response(code, msg):
    return {
        'statusCode': code,
        'body': msg
    }


def invoke_process_lambda(batch_id, data, lambda_name):
    # Create payload to be sent to processing lambda
    invoke_payload = json.dumps({
        BATCH_ID_STRING: batch_id,
        DATA_STRING: data
    })

    # Invoke processing lambda asynchronously by using InvocationType='Event'.
    # This allows the processing to continue while the POST handler returns HTTP 202.
    lambda_client = boto3.client('lambda', region_name=REGION_NAME,)
    lambda_response = lambda_client.invoke(
        FunctionName=lambda_name,
        InvocationType='Event',
        Payload=invoke_payload
    )
    # returns 202 on success if InvocationType = 'Event'
    return lambda_response


def write_to_storage(batch_id, status, data):
    # we assume that the table has already been created
    client = boto3.resource('dynamodb')
    table = client.Table(TABLE_NAME)

    # Put in progress item in table
    item_to_store = {
        'batch_id': batch_id,
        'status': status,
        'data': data,
        'timestamp': "{}".format(time.time())
    }
    db_response = table.put_item(
        Item=item_to_store
    )


def read_data_from_storage(batch_id):
    # we assume that the table has already been created
    client = boto3.resource('dynamodb')
    table = client.Table(TABLE_NAME)

    response = table.get_item(Key={'batch_id': batch_id},
                          ConsistentRead=True)
    return response

Hier ist ein Beispielaufruf der asynchronen externen Funktion zusammen mit einer Beispielausgabe, einschließlich der Ergebnisse der Standpunktanalyse:

create table test_tb(a string);
insert into test_tb values
    ('hello world'),
    ('I am happy');
select ext_func_async(a) from test_tb;

Row | EXT_FUNC_ASYNC(A)
0   | {"Positive": 0.47589144110679626, "Negative": 0.07314028590917587, "Neutral": 0.4493273198604584, "Mixed": 0.0016409909585490823}
1   | {"Positive": 0.9954453706741333, "Negative": 0.00039307220140472054, "Neutral": 0.002452891319990158, "Mixed": 0.0017087293090298772}

Hinweise zum Beispielcode:

  • Die Datenverarbeitungsfunktion wird durch Aufruf gestartet:

    lambda_response = lambda_client.invoke(
        ...
        InvocationType='Event',
        ...
    )
    

    Der InvocationType sollte, wie oben gezeigt, „Event“ (Ereignis) sein, weil der zweite Prozess (oder Thread) asynchron sein muss und Event der einzige Typ von nicht blockierendem Aufruf ist, der durch die invoke()-Methode verfügbar ist.

  • Die Datenverarbeitungsfunktion gibt einen HTTP 200-Code zurück. Dieser HTTP 200-Code wird jedoch nicht direkt an Snowflake zurückgegeben. Snowflake erkennt so langen keinen HTTP 200-Code, bis mit GET der Status abgefragt und somit festgestellt wird, ob die Datenverarbeitungsfunktion die Verarbeitung dieses Batches erfolgreich abgeschlossen hat.

Problembehandlung bei externen Funktionen auf AWS

Plattformunabhängige Symptome

Die tatsächlichen Rückgabewerte für einen Datentyp stimmen nicht mit den erwarteten Rückgabewerten überein

Achten Sie beim Übergeben von Argumenten an oder von einer externen Funktion darauf, dass die passenden Datentypen verwendet werden. Wenn der gesendete Wert nicht zum Datentyp des Empfängers passt, wird der Wert möglicherweise abgeschnitten oder auf andere Weise beschädigt.

Weitere Details dazu finden Sie unter Sicherstellen, dass Argumente der externen Funktion den Argumenten des Remotedienstes entsprechen.

Beim Aufrufen der Funktion mit SQL wird eine Meldung angezeigt, dass die Zeilennummerierung nicht korrekt ist

Mögliche Ursachen

Denken Sie daran, dass die von Ihnen innerhalb jedes Batches zurückgegebenen Zeilennummern monoton aufsteigende Ganzzahlen sein müssen, die bei 0 beginnen. Die Eingabezeilennummern müssen ebenfalls dieser Regel folgen, und jede Ausgabezeile muss mit der entsprechenden Eingabezeile übereinstimmen. So sollte beispielsweise die Ausgabe von Ausgabezeile 0 der Eingabe von Eingabezeile 0 entsprechen.

Mögliche Lösungen
  1. Stellen Sie sicher, dass die von Ihnen zurückgegebenen Zeilennummern mit den erhaltenen Zeilennummern übereinstimmen und dass jeder Ausgabewert die Zeilennummer der entsprechenden Eingabe verwendet. Das sollte funktionieren. Wenn dies nicht der Fall ist, sind möglicherweise die eingegebenen Zeilennummern nicht korrekt oder die Zeilen wurden nicht in der richtigen Reihenfolge zurückgegeben. Fahren Sie daher mit Schritt 2 fort.

  2. Stellen Sie sicher, dass die Ausgabezeilennummern bei 0 beginnen, um 1 erhöht werden und in der richtigen Reihenfolge sind.

Weitere Informationen zu Dateneingabe- und Datenausgabeformaten finden Sie unter Eingabe- und Ausgabedatenformate von Remotediensten.

Beim Versuch, die externe Funktion aufzurufen, wird die Meldung „Error parsing JSON: Invalid response“ angezeigt

Mögliche Ursachen

Die wahrscheinlichste Ursache ist, dass die vom Remotedienst zurückgegebenen JSON-Daten (z. B. AWS Lambda-Funktion) nicht korrekt erstellt wurde.

Mögliche Lösungen

Stellen Sie sicher, dass Sie ein Array von Arrays zurückgeben, wobei für jede empfangene Eingabezeile ein inneres Array zurückgegeben wird. Überprüfen Sie die Beschreibung des Ausgabeformats unter Von Snowflake empfangenes Datenformat.

Eine Fehlermeldung besagt, dass das Format des zurückgegebenen Werts nicht JSON ist

Mögliche Ursachen

Eine mögliche Ursache hierfür ist, dass Ihr Rückgabewert doppelte Anführungszeichen enthält.

Mögliche Lösungen

Obwohl JSON-Zeichenfolgen durch doppelte Anführungszeichen getrennt sind, sollte die Zeichenfolge selbst in den meisten Fällen nicht mit einem Anführungszeichen beginnen und enden. Wenn die eingebetteten doppelten Anführungszeichen falsch sind, entfernen Sie diese.

Eine Fehlermeldung besagt, dass die Funktion die falsche Anzahl von Zeilen erhält

Mögliche Ursachen

Der Remotedienst hat wahrscheinlich versucht, mehr oder weniger Zeilen zurückzugeben, als er erhalten hat. (Denken Sie daran, dass die Funktion, obwohl sie nominell skalar ist, möglicherweise im Feld „body“ des Parameters „event“ mehrere Zeilen empfängt und genau so viele Zeilen zurückgeben sollte, wie sie empfangen hat.)

Mögliche Lösungen

Stellen Sie sicher, dass der Remotedienst für jede erhaltene Zeile genau eine Zeile zurückgibt.

Plattformspezifische Symptome

API Gateway gibt Fehler 502 zurück, wenn der Endpunkt die Lambda-Proxyintegration verwendet

Mögliche Ursachen

Die Lambda-Funktion könnte folgendes Problem haben:

  • Timeout

  • Ausnahme ausgelöst

  • Auf andere Weise fehlgeschlagen

Mögliche Lösungen

Wenn Ihnen die Lambda- oder API Gateway-Protokolle zur Verfügung stehen, überprüfen Sie diese.

Wenn Ihnen der Quellcode der Lambda-Funktion zur Verfügung steht, dann analysieren und debuggen Sie den Code der Lambda-Funktion. In einigen Fällen können Sie möglicherweise eine Kopie dieses Codes in einem einfacheren Kontext (außerhalb von AWS) ausführen, um das Debuggen zu erleichtern.

Stellen Sie sicher, dass die an die Lambda-Funktion gesendeten Daten das von der Lambda-Funktion erwartete Format haben. Sie können versuchen, ein kleineres, einfacheres Dataset zu senden, um festzustellen, ob dies erfolgreich ist.

Stellen Sie sicher, dass Sie nicht zu viele Daten gleichzeitig senden.

In einigen Fällen kann das Problem durch Erhöhen des Timeouts behoben werden, insbesondere wenn die Lambda-Funktion viele CPU-Ressourcen benötigt oder wenn die Lambda-Funktion selbst andere Remotedienste aufruft und daher mehr Zeit benötigt.

Unable to read the requests body in the HTTP POST method inside the Amazon AWS Lambda Function

Mögliche Ursachen

Möglicherweise haben Sie die Lambda-Proxyintegration nicht aktiviert.

Mögliche Lösungen

Aktivieren Sie die Lambda-Proxyintegration.

Weitere Informationen dazu finden Sie unter API im Amazon-API-Gateway erstellen und konfigurieren.

Error assuming AWS_ROLE

Der vollständige Text der Meldung lautet:

SQL execution error: Error assuming AWS_ROLE. Please verify the role and externalId are
configured correctly in your AWS policy.
Mögliche Ursachen
  • In der AWS Trust Relationship Policy für Ihre Rolle ist ein falscher AWS-ARN angegeben. Mögliche Ursachen hierfür sind:

    • Sie haben den Wert nicht angegeben.

    • Sie haben einen Wert angegeben, aber Sie haben anstelle des Benutzer-ARN den ARN der AWS-Rolle (falsch) verwendet, was Sie mit dem DESCRIBE INTEGRATION-Befehl in Snowflake prüfen können. Achten Sie darauf, dass Sie den Wert aus dem Feld „API_AWS_IAM_USER_ARN“ des Arbeitsblatts verwenden und nicht den Wert aus dem Feld „API_AWS_ROLE_ARN“.

  • In Ihrer AWS Trust Relationship Policy ist ein falscher Wert für std:ExternalId angegeben. Mögliche Ursachen hierfür sind:

    • Sie haben den Wert nicht angegeben.

    • Sie haben das API-Integrationsobjekt neu erstellt. Durch das erneute Erstellen des API-Objekts wird die externe ID geändert.

Error: 403 ‚{„Message“:“User: <ARN> is not authorized to perform: execute-api:Invoke“}‘

Der vollständige Text der Meldung lautet:

Request failed for external function <function_name>.
Error: 403 '{"Message":"User: <ARN> is not authorized to perform: execute-api:Invoke on resource: <MethodRequestARN>"}'
Mögliche Ursachen
  • Die API Gateway-Ressourcenrichtlinie hat:

    • Den falschen IAM-Rollen-ARN.

    • Die falsch angenommene Rolle.

    • Den falschen Methodenanforderungs-ARN.

  • Der IAM-Rolle ist nicht die richtige Richtlinie zugeordnet.

Mögliche Lösungen
  • Stellen Sie sicher, dass Sie die Ressourcenrichtlinienvorlage in Amazon API Gateway-Endpunkt sichern befolgt haben. Stellen Sie insbesondere sicher, dass für Ihre Ressourcenrichtlinie Folgendes gilt:

    • Die <12-digit number> wurde durch den Wert im Feld „AWS account ID“ des Arbeitsblatts ersetzt.

    • Die <external_function_role> wurde durch den Wert im Feld „New IAM Role Name“ des Arbeitsblatts ersetzt.

    • Der method_request_ARN im Feld Resource wurde durch den Wert im Feld „Method Request ARN“ des Arbeitsblatts ersetzt.

  • Wenn Sie sicherstellen müssen, dass der IAM-Rolle die korrekte Berechtigungsrichtlinie zugeordnet ist, können Sie die Liste der Berechtigungsrichtlinien der Rolle erhalten, indem Sie die folgenden Schritte ausführen:

    1. Wählen Sie in AWS die Rolle aus.

    2. Zeigen Sie die Summary für die Rolle an.

    3. Klicken Sie auf die Registerkarte Permissions.

    4. Überprüfen Sie, ob die gewünschte Richtlinie in der Liste Permissions policies enthalten ist.

Error: 403 ‚{„Message“:“User: anonymous is not authorized to perform: execute-api:Invoke“}‘

Der vollständige Text der Meldung lautet:

Request failed for external function <function_name>.
Error: 403 '{"Message":"User: anonymous is not authorized to perform: execute-api:Invoke on resource: <MethodRequestARN>"}'
Mögliche Ursachen

Eine mögliche Ursache ist, dass Sie bei der Konfiguration der Autorisierung für das API Gateway nicht angegeben haben, dass der Method Request eine AWS_IAM-Autorisierung für die Ressource benötigt.

Mögliche Lösungen

Wenn Sie die Anweisungen zum Sichern des Amazon API Gateway nicht befolgt haben, dann befolgen Sie diese jetzt, um die AWS_IAM-Autorisierung anzugeben.

Error parsing JSON response … Error: top-level JSON object must contain „data“ JSON array element

Der vollständige Text der Meldung lautet:

Error parsing JSON response for external function ... Error: top-level JSON object must contain "data" JSON array element
Mögliche Ursachen
  • Möglicherweise haben Sie die Lambda-Proxyintegration für den POST-Befehl nicht in Ihrer API Gateway-Ressource angegeben.

Mögliche Lösungen

Request failed for external function EXT_FUNC with remote service error: 403 ‚{„message“:“Forbidden“}‘;

Mögliche Ursachen

Der Proxydienst benötigt einen API-Schlüssel, typischerweise zur Authentifizierung oder Abrechnung. Der API-Schlüssel fehlt oder ist falsch.

Mögliche Lösungen

Verwenden Sie den Befehl ALTER API INTEGRATION, um den korrekten API-Schlüssel anzugeben.