Verbinden von Azure Functions mit Azure SQL-Datenbank mithilfe von Visual Studio Code

Azure Functions gestattet Ihnen das Verbinden von Azure-Diensten und anderen Ressourcen mit Funktionen, ohne dass Sie Ihren eigenen Integrationscode schreiben müssen. Diese Bindungen, die sowohl Eingabe als auch Ausgabe darstellen, werden innerhalb der Funktionsdefinition deklariert. Daten von Bindungen werden der Funktion als Parameter bereitgestellt. Ein Trigger ist ein spezieller Typ von Eingabebindung. Eine Funktion hat zwar nur einen Trigger, kann aber mehrere Ein- und Ausgabebindungen haben. Weitere Informationen finden Sie unter Konzepte der Trigger und Bindungen in Azure Functions.

In diesem Artikel wird gezeigt, wie Sie Visual Studio Code verwenden, um Azure SQL-Datenbank mit der Funktion zu verbinden, die Sie im vorherigen Schnellstartartikel erstellt haben. Die Ausgabebindung, die Sie dieser Funktion hinzufügen, schreibt Daten aus der HTTP-Anforderung in eine Tabelle in Azure SQL-Datenbank.

Bevor Sie beginnen, müssen Sie die Schritte unter Schnellstart: Erstellen einer C#-Funktion in Azure mit Visual Studio Code ausführen. Falls Sie die Ressourcen am Ende dieses Artikels bereits bereinigt haben, sollten Sie die Schritte erneut ausführen, um die Funktions-App und die zugehörigen Ressourcen neu zu erstellen.

Bevor Sie beginnen, müssen Sie die Schritte unter Schnellstart: Erstellen einer Java-Funktion in Azure mit Visual Studio Code ausführen. Falls Sie die Ressourcen am Ende dieses Artikels bereits bereinigt haben, sollten Sie die Schritte erneut ausführen, um die Funktions-App und die zugehörigen Ressourcen neu zu erstellen.

Bevor Sie beginnen, müssen Sie die Schritte unter Schnellstart: Erstellen einer Funktion in Azure mit Python mithilfe von Visual Studio Code ausführen. Falls Sie die Ressourcen am Ende dieses Artikels bereits bereinigt haben, sollten Sie die Schritte erneut ausführen, um die Funktions-App und die zugehörigen Ressourcen neu zu erstellen.

Weitere Informationen zu den Einstellungen für Azure SQL-Bindungen und -Trigger für Azure Functions finden Sie in der Dokumentation zu Azure Functions.

Erstellen der Azure SQL-Datenbank

  1. Befolgen Sie den Schnellstart: Erstellen einer Azure SQL-Datenbank-Instanz, um eine serverlose Azure SQL-Datenbank-Instanz zu erstellen. Die Datenbank kann leer sein oder aus dem Beispieldataset „AdventureWorksLT“ erstellt werden.

  2. Geben Sie nach entsprechender Aufforderung Folgendes ein:

    Prompt Auswahl
    Ressourcengruppe Wählen Sie die Ressourcengruppe aus, in der Sie im vorherigen Artikel Ihre Funktions-App erstellt haben.
    Datenbankname Gib mySampleDatabase ein.
    Servername Geben Sie einen eindeutigen Namen für Ihren Server ein. Wir können keinen exakten Servernamen zur Verwendung angeben, weil Servernamen für alle Server in Azure global eindeutig sein müssen (und nicht nur innerhalb eines Abonnements eindeutig sind).
    Authentifizierungsmethode Wählen Sie SQL Server-Authentifizierung aus.
    Serveradministratoranmeldung Geben Sie azureuser ein.
    Kennwort Geben Sie ein Kennwort ein, das die Komplexitätsanforderungen erfüllt.
    Azure-Diensten und -Ressourcen den Zugriff auf diesen Server erlauben Wählen Sie Ja.
  3. Navigieren Sie nach Abschluss der Erstellung im Azure-Portal zum Datenbankblatt, und wählen Sie unter Einstellungen die Option Verbindungszeichenfolgen aus. Kopieren Sie die ADO.NET-Verbindungszeichenfolge für die SQL-Authentifizierung. Fügen Sie die Verbindungszeichenfolge zur späteren Verwendung in ein temporäres Dokument ein.

    Screenshot des Kopierens einer Azure SQL-Datenbank-Verbindungszeichenfolge im Azure-Portal

  4. Erstellen Sie eine Tabelle zum Speichern der Daten aus der HTTP-Anforderung. Navigieren Sie im Azure-Portal zum Datenbankblatt, und wählen Sie Abfrage-Editor aus. Geben Sie die folgende Abfrage ein, um eine neue Tabelle namens dbo.ToDo zu erstellen:

    CREATE TABLE dbo.ToDo (
        [Id] UNIQUEIDENTIFIER PRIMARY KEY,
        [order] INT NULL,
        [title] NVARCHAR(200) NOT NULL,
        [url] NVARCHAR(200) NOT NULL,
        [completed] BIT NOT NULL
    );
    
  5. Überprüfen Sie in den Firewalleinstellungen des Servers, ob Ihre Azure-Funktion auf die Azure SQL-Datenbank-Instanz zugreifen kann. Navigieren Sie im Azure-Portal zum Blatt des Servers, und wählen Sie unter Sicherheit die Option Netzwerk aus. Die Ausnahme für Azure-Diensten und -Ressourcen den Zugriff auf diesen Server gestatten sollte aktiviert sein.

    Screenshot der Überprüfung der Firewalleinstellungen von Azure SQL-Datenbank im Azure-Portal

Aktualisieren der Einstellungen Ihrer Funktions-App

Im vorherigen Schnellstartartikel haben Sie eine Funktions-App in Azure erstellt. In diesem Artikel aktualisieren Sie Ihre App, um Daten in die Azure SQL-Datenbank-Instanz zu schreiben, den Sie gerade erstellt haben. Zum Herstellen einer Verbindung mit Ihrer Azure SQL-Datenbank-Instanz müssen Sie die zugehörige Verbindungszeichenfolge den App-Einstellungen hinzufügen. Anschließend laden Sie die neue Einstellung in Ihre Datei „local.settings.js“ herunter, damit Sie bei der lokalen Ausführung eine Verbindung mit Ihrer Azure SQL-Datenbank-Instanz herstellen können.

  1. Bearbeiten Sie die Verbindungszeichenfolge in dem temporären Dokument, das Sie zuvor erstellt haben. Ersetzen Sie den Wert von Password durch das Kennwort, das Sie beim Erstellen der Azure SQL-Datenbank-Instanz verwendet haben. Kopieren Sie die aktualisierte Verbindungszeichenfolge.

  2. Drücken Sie STRG/BEFEHL+UMSCHALT+P, um die Befehlspalette zu öffnen. Suchen Sie dann den Befehl Azure Functions: Add New Setting..., und führen Sie ihn aus.

  3. Wählen Sie die im vorherigen Artikel erstellte Funktions-App aus. Geben Sie nach entsprechender Aufforderung Folgendes ein:

    Prompt Auswahl
    Geben Sie den Namen der neuen App-Einstellung ein Geben Sie SqlConnectionStringein.
    Geben Sie einen Wert für „SqlConnectionString“ ein Fügen Sie die soeben kopierte Verbindungszeichenfolge Ihrer Azure SQL-Datenbank-Instanz ein.

    Dadurch wird eine Anwendungseinstellung namens „Verbindung SqlConnectionString„ in Ihrer Funktions-App in Azure erstellt. Jetzt können Sie diese Einstellung in Ihre Datei local.settings.json herunterladen.

  4. Drücken Sie erneut STRG/BEFEHL+UMSCHALT+P, um die Befehlspalette zu öffnen. Suchen Sie dann den Befehl Azure Functions: Download Remote Settings..., und führen Sie ihn aus.

  5. Wählen Sie die im vorherigen Artikel erstellte Funktions-App aus. Wählen Sie Ja, alle aus, um die vorhandenen lokalen Einstellungen zu überschreiben.

Dadurch werden alle Einstellungen aus Azure in Ihr lokales Projekt heruntergeladen, einschließlich der neuen Einstellung für die Verbindungszeichenfolge. Die meisten heruntergeladenen Einstellungen werden bei der lokalen Ausführung nicht verwendet.

Registrieren von Bindungserweiterungen

Da Sie eine Azure SQL-Ausgabebindung verwenden, müssen Sie vor dem Ausführen des Projekts die entsprechende Bindungserweiterung installieren.

Mit Ausnahme von HTTP- und Timertriggern werden Bindungen als Erweiterungspakete implementiert. Führen Sie den folgenden dotnet add package-Befehl im Terminalfenster aus, um Ihrem Projekt das Azure SQL-Erweiterungspaket hinzuzufügen.

dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Sql

Ihr Projekt wurde für die Verwendung von Erweiterungsbündeln konfiguriert, wodurch automatisch ein vordefinierter Satz von Erweiterungspaketen installiert wird.

Die Nutzung von Erweiterungspaketen ist in der Datei host.json im Stammverzeichnis des Projekts aktiviert. Dies sieht wie folgt aus:

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  },
  "concurrency": {
    "dynamicConcurrencyEnabled": true,
    "snapshotPersistenceEnabled": true
  }
}

:::

Jetzt können Sie die Azure SQL-Ausgabebindung Ihrem Projekt hinzufügen.

Hinzufügen einer Ausgabebindung

In Functions muss für jeden Typ von Bindung eine direction, ein type und ein eindeutiger name in der Datei „function.json“ definiert werden. Wie Sie diese Attribute definieren, hängt von der Sprache der Funktions-App ab.

Öffnen Sie die Projektdatei HttpExample.cs, und fügen Sie die folgende ToDoItem-Klasse hinzu, die das Objekt definiert, das in die Datenbank geschrieben wird:

namespace AzureSQL.ToDo
{
    public class ToDoItem
    {
        public Guid Id { get; set; }
        public int? order { get; set; }
        public string title { get; set; }
        public string url { get; set; }
        public bool? completed { get; set; }
    }
}

In einem C#-Klassenbibliotheksprojekt werden die Bindungen als Bindungsattribute der Funktionsmethode definiert. Die von Functions benötigte Datei function.json wird basierend auf diesen Attributen automatisch generiert.

Öffnen Sie die Projektdatei HttpExample.cs, und fügen Sie die folgende Ausgabetypklasse hinzu, die die kombinierten Objekte definiert, die von der Funktion sowohl für die HTTP-Antwort als auch für die SQL-Ausgabe ausgegeben werden:

public static class OutputType
{
    [SqlOutput("dbo.ToDo", connectionStringSetting: "SqlConnectionString")]
    public ToDoItem ToDoItem { get; set; }
    public HttpResponseData HttpResponse { get; set; }
}

Fügen Sie der Bibliothek Microsoft.Azure.Functions.Worker.Extensions.Sql am Anfang der Datei eine using-Anweisung hinzu:

using Microsoft.Azure.Functions.Worker.Extensions.Sql;

Bindungsattribute werden direkt in Ihrem Code definiert. In der Azure SQL-Datenbank-Ausgabekonfiguration werden die für eine Azure SQL-Ausgabebindung erforderlichen Felder beschrieben.

Für dieses MultiResponse-Szenario müssen Sie der Funktion eine Ausgabebindung vom Typ extraOutputs hinzufügen.

app.http('HttpExample', {
  methods: ['GET', 'POST'],
  extraOutputs: [sendToSql],
  handler: async (request, context) => {

Fügen Sie der Bindungskonfiguration die folgenden Eigenschaften hinzu:

const sendToSql = output.sql({
  commandText: 'dbo.ToDo',
  connectionStringSetting: 'SqlConnectionString',
});

Bindungsattribute werden direkt in der Datei function_app.py definiert. Sie verwenden den generic_output_binding-Decorator, um eine Azure SQL-Ausgabebindung hinzuzufügen:

@app.generic_output_binding(arg_name="toDoItems", type="sql", CommandText="dbo.ToDo", ConnectionStringSetting="SqlConnectionString"
    data_type=DataType.STRING)

In diesem Code identifiziert arg_name den Bindungsparameter, auf den in Ihrem Code verwiesen wird. type gibt an, dass die Ausgabebindung eine SQL-Ausgabebindung ist. CommandText ist die Tabelle, in die die Bindung schreibt, und ConnectionStringSetting ist der Name einer Anwendungseinstellung, die die Azure SQL-Verbindungszeichenfolge enthält. Die Verbindungszeichenfolge befindet sich in der SqlConnectionString-Einstellung in der Datei local.settings.json.

Hinzufügen von Code, der die Ausgabebindung verwendet

Ersetzen Sie die vorhandene Ausführungsmethode durch den folgenden Code:

[Function("HttpExample")]
public static OutputType Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
    FunctionContext executionContext)
{
    var logger = executionContext.GetLogger("HttpExample");
    logger.LogInformation("C# HTTP trigger function processed a request.");

    var message = "Welcome to Azure Functions!";

    var response = req.CreateResponse(HttpStatusCode.OK);
    response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
    response.WriteString(message);

    // Return a response to both HTTP trigger and Azure SQL output binding.
    return new OutputType()
    {
         ToDoItem = new ToDoItem
        {
            id = System.Guid.NewGuid().ToString(),
            title = message,
            completed = false,
            url = ""
        },
        HttpResponse = response
    };
}

Fügen Sie Code hinzu, der das extraInputs-Ausgabebindungsobjekt für context verwendet, um ein JSON-Dokument an die benannte Ausgabebindungsfunktion sendToSql zu senden. Fügen Sie diesen Code vor der return-Anweisung hinzu.

const data = JSON.stringify([
  {
    // create a random ID
    Id: crypto.randomUUID(),
    title: name,
    completed: false,
    url: '',
  },
]);

// Output to Database
context.extraOutputs.set(sendToSql, data);

Um das crypto-Modul zu verwenden, fügen Sie am Anfang der Datei die folgende Zeile hinzu:

const crypto = require("crypto");

Die Funktion sollte nun wie folgt aussehen:

const { app, output } = require('@azure/functions');
const crypto = require('crypto');

const sendToSql = output.sql({
  commandText: 'dbo.ToDo',
  connectionStringSetting: 'SqlConnectionString',
});

app.http('HttpExample', {
  methods: ['GET', 'POST'],
  extraOutputs: [sendToSql],
  handler: async (request, context) => {
    try {
      context.log(`Http function processed request for url "${request.url}"`);

      const name = request.query.get('name') || (await request.text());

      if (!name) {
        return { status: 404, body: 'Missing required data' };
      }

      // Stringified array of objects to be inserted into the database
      const data = JSON.stringify([
        {
          // create a random ID
          Id: crypto.randomUUID(),
          title: name,
          completed: false,
          url: '',
        },
      ]);

      // Output to Database
      context.extraOutputs.set(sendToSql, data);

      const responseMessage = name
        ? 'Hello, ' +
          name +
          '. This HTTP triggered function executed successfully.'
        : 'This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.';

      // Return to HTTP client
      return { body: responseMessage };
    } catch (error) {
      context.log(`Error: ${error}`);
      return { status: 500, body: 'Internal Server Error' };
    }
  },
});

Aktualisieren Sie HttpExample\function_app.py dem folgenden Code entsprechend. Fügen Sie dem Parameter toDoItems die Funktionsdefinition und toDoItems.set() unter der if name:-Anweisung hinzu:

import azure.functions as func
import logging
from azure.functions.decorators.core import DataType
import uuid

app = func.FunctionApp()

@app.function_name(name="HttpTrigger1")
@app.route(route="hello", auth_level=func.AuthLevel.ANONYMOUS)
@app.generic_output_binding(arg_name="toDoItems", type="sql", CommandText="dbo.ToDo", ConnectionStringSetting="SqlConnectionString",data_type=DataType.STRING)
def test_function(req: func.HttpRequest, toDoItems: func.Out[func.SqlRow]) -> func.HttpResponse:
     logging.info('Python HTTP trigger function processed a request.')
     name = req.get_json().get('name')
     if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

     if name:
        toDoItems.set(func.SqlRow({"Id": str(uuid.uuid4()), "title": name, "completed": False, "url": ""}))
        return func.HttpResponse(f"Hello {name}!")
     else:
        return func.HttpResponse(
                    "Please pass a name on the query string or in the request body",
                    status_code=400
                )

Lokales Ausführen der Funktion

Dank der Integration zwischen Visual Studio Code und Azure Functions Core Tools können Sie dieses Projekt vor der Veröffentlichung in Azure zunächst auf Ihrem lokalen Entwicklungscomputer ausführen. Wenn Sie Core Tools noch nicht lokal installiert haben, werden Sie beim ersten Ausführen des Projekts aufgefordert, die Installation auszuführen.

  1. Drücken Sie zum Aufrufen Ihrer Funktion F5, um das Funktions-App-Projekt zu starten. Im Terminalbereich wird die Ausgabe aus den Core Tools angezeigt. Ihre App wird im Terminal-Bereich gestartet. Der lokal ausgeführte URL-Endpunkt Ihrer über HTTP ausgelösten Funktion wird angezeigt.

    Der Screenshot der Visual Studio Code-Ausgabe der lokalen Funktion.

    Wenn Sie Core Tools noch nicht installiert haben, wählen Sie Installieren aus, um die Installation auszuführen, wenn Sie dazu aufgefordert werden.
    Sollten bei der Ausführung unter Windows Probleme auftreten, vergewissern Sie sich, dass das Standardterminal für Visual Studio Code nicht auf WSL Bash festgelegt ist.

  2. Navigieren Sie bei ausgeführten Core Tools zum Bereich Azure: Funktionen. Erweitern Sie unter Functions die Option Lokales Projekt>Functions. Klicken Sie unter Windows mit der rechten Maustaste (unter macOS STRG+Mausklick) auf die Funktion HttpExample, und wählen Sie Funktion jetzt ausführen... aus.

    Der Screenshot der Ausführungsfunktion jetzt aus Visual Studio Code.

  3. Drücken Sie in Anforderungstext eingeben die EINGABETASTE, um eine Anforderungsnachricht an Ihre Funktion zu übermitteln.

  4. Wenn die Funktion lokal ausgeführt wird und eine Antwort zurückgibt, wird in Visual Studio Code eine Benachrichtigung ausgelöst. Informationen zur Funktionsausführung werden im Terminalbereich angezeigt.

  5. Drücken Sie STRG+C, um die Core Tools zu beenden und die Verbindung mit dem Debugger zu trennen.

Lokales Ausführen der Funktion

  1. Drücken Sie wie im vorherigen Artikel die F5-TASTE, um das Funktions-App-Projekt und die Core Tools zu starten.

  2. Navigieren Sie bei ausgeführten Core Tools zum Bereich Azure: Functions. Erweitern Sie unter Functions die Option Lokales Projekt>Functions. Klicken Sie mit der rechten Maustaste (unter macOS STRG+Mausklick) auf die Funktion HttpExample, und wählen Sie Funktion jetzt ausführen... aus.

    Screenshot des Menüelements „Funktion jetzt ausführen“ in Visual Studio Code

  3. Unter Enter request body (Anforderungstext eingeben) wird { "name": "Azure" } als Wert für den Text der Anforderungsnachricht angezeigt. Drücken Sie die EINGABETASTE, um diese Anforderungsnachricht an Ihre Funktion zu senden.

  4. Drücken Sie nach der Rückgabe einer Antwort STRG+C, um Core Tools zu beenden.

Überprüfen, ob Informationen in die Datenbank geschrieben wurden

  1. Navigieren Sie im Azure-Portal zurück zu Ihrer Azure SQL-Datenbank-Instanz, und wählen Sie Abfrage-Editor aus.

    Screenshot der Protokollierung im Abfrage-Editor im Azure-Portal

  2. Stellen Sie eine Verbindung mit Ihrer Datenbank her, und erweitern Sie im Objekt-Explorer auf der linken Seite den Knoten Tabellen. Klicken Sie mit der rechten Maustaste auf die Tabelle dbo.ToDo, und wählen Sie Oberste 1.000 Zeilen auswählen aus.

  3. Überprüfen Sie, ob die neuen Informationen von der Ausgabebindung in die Datenbank geschrieben wurden.

Erneutes Bereitstellen und Überprüfen der aktualisierten App

  1. Drücken Sie in Visual Studio Code F1, um die Befehlspalette zu öffnen. Suchen Sie in der Befehlspalette den Befehl Azure Functions: Deploy to function app..., und wählen Sie ihn aus.

  2. Wählen Sie die im ersten Artikel erstellte Funktions-App aus. Da Sie das Projekt für die gleiche App erneut bereitstellen, wählen Sie Bereitstellen aus, um die Warnung zum Überschreiben von Dateien zu schließen.

  3. Nach Abschluss des Bereitstellungsvorgangs können Sie das Feature Funktion jetzt ausführen... erneut verwenden, um die Funktion in Azure auszulösen.

  4. Überprüfen Sie erneut, ob Daten in Ihre Azure SQL-Datenbank-Instanz geschrieben wurden, um sicherzustellen, dass die Ausgabebindung erneut ein neues JSON-Dokument generiert.

Bereinigen von Ressourcen

In Azure wird die Bezeichnung Ressourcen für Funktions-Apps, Funktionen, Speicherkonten usw. verwendet. Sie werden in Ressourcengruppen zusammengefasst, und sämtliche Inhalte einer Gruppe können durch das Löschen der Gruppe gelöscht werden.

Im Rahmen dieser Schnellstartanleitungen haben Sie Ressourcen erstellt. Für diese Ressourcen fallen je nach Kontostatus und Dienstpreisen unter Umständen Kosten an. Nicht mehr benötigte Ressourcen können wie folgt gelöscht werden:

  1. Drücken Sie in Visual Studio Code F1, um die Befehlspalette zu öffnen. Suchen Sie in der Befehlspalette den Befehl Azure: Open in portal, und wählen Sie ihn aus.

  2. Wählen Sie Ihre Funktions-App aus, und drücken Sie die EINGABETASTE. Die Seite der Funktions-App wird im Azure-Portal geöffnet.

  3. Wählen Sie auf der Registerkarte Übersicht den benannten Link neben Ressourcengruppe aus.

    Screenshot: Auswählen der Ressourcengruppe, die von der Funktions-App-Seite gelöscht werden soll.

  4. Überprüfen Sie auf der Seite Ressourcengruppe die Liste mit den enthaltenen Ressourcen, und vergewissern Sie sich, dass es sich dabei um die Ressourcen handelt, die Sie löschen möchten.

  5. Klicken Sie auf Ressourcengruppe löschen, und folgen Sie den Anweisungen.

    Der Löschvorgang kann einige Minuten dauern. Nach Abschluss des Vorgangs wird kurz eine Benachrichtigung angezeigt. Sie können auch am oberen Seitenrand auf das Glockensymbol klicken, um die Benachrichtigung anzuzeigen.

Nächste Schritte

Sie haben Ihre per HTTP ausgelöste Funktion so aktualisiert, dass sie Daten in eine Azure SQL-Datenbank-Instanz schreibt. Nun können Sie sich ausführlicher über die Entwicklung von Funktionen mit Visual Studio Code informieren: