Connessione Funzioni di Azure per database SQL di Azure con Visual Studio Code

La soluzione Funzioni di Azure consente di connettere i servizi di Azure e altre risorse alle funzioni senza la necessità di scrivere codice di integrazione personalizzato. Questi binding, che rappresentano sia input che output, vengono dichiarati all'interno della definizione di funzione. I dati dei binding vengono forniti alla funzione come parametri. Un trigger è un tipo speciale di binding di input. Anche se una funzione include un solo trigger, può avere più binding di input e output. Per altre informazioni, vedere Concetti su trigger e binding di Funzioni di Azure.

Questo articolo illustra come usare Visual Studio Code per connettere database SQL di Azure alla funzione creata nell'articolo di avvio rapido precedente. L'associazione di output aggiunta a questa funzione scrive i dati dalla richiesta HTTP in una tabella in database SQL di Azure.

Prima di iniziare, è necessario completare la guida introduttiva: Creare una funzione C# in Azure usando Visual Studio Code. Se è già stata eseguita la pulizia delle risorse alla fine di tale articolo, eseguire di nuovo i passaggi per ricreare l'app per le funzioni e le risorse correlate in Azure.

Prima di iniziare, è necessario completare la guida introduttiva: Creare una funzione JavaScript in Azure usando Visual Studio Code. Se è già stata eseguita la pulizia delle risorse alla fine di tale articolo, eseguire di nuovo i passaggi per ricreare l'app per le funzioni e le risorse correlate in Azure.

Prima di iniziare, è necessario completare la guida introduttiva: Creare una funzione Python in Azure usando Visual Studio Code. Se è già stata eseguita la pulizia delle risorse alla fine di tale articolo, eseguire di nuovo i passaggi per ricreare l'app per le funzioni e le risorse correlate in Azure.

Altre informazioni sulle impostazioni per le associazioni e i trigger SQL di Azure per Funzioni di Azure sono disponibili nella documentazione Funzioni di Azure.

Creare il database SQL di Azure

  1. Seguire la guida introduttiva database SQL di Azure creare un database SQL di Azure serverless. Il database può essere vuoto o creato dal set di dati di esempio AdventureWorksLT.

  2. Quando richiesto, immettere le informazioni seguenti:

    Richiesta Selezione
    Gruppo di risorse Scegliere il gruppo di risorse in cui è stata creata l'app per le funzioni nell'articolo precedente.
    Nome database Immetti mySampleDatabase.
    Nome server Immettere un nome univoco per il server. Non è possibile specificare un nome del server esatto da usare perché i nomi di tutti i server di Azure devono essere univoci a livello globale, oltre che univoci all’interno di una sottoscrizione.
    Metodo di autenticazione Selezionare Autenticazione di SQL Server.
    Accesso amministratore server Immetti azureuser.
    Password Immettere una password che soddisfi i requisiti di complessità.
    Consentire ai servizi e alle risorse di Azure di accedere a questo server Selezionare .
  3. Al termine della creazione, passare al pannello del database nel portale di Azure e, in Impostazioni, selezionare Connessione stringhe di Connessione. Copiare il stringa di connessione ADO.NET per l'autenticazione SQL. Incollare il stringa di connessione in un documento temporaneo per un uso successivo.

    Screenshot della copia del database SQL di Azure stringa di connessione nel portale di Azure.

  4. Creare una tabella per archiviare i dati dalla richiesta HTTP. Nel portale di Azure passare al pannello del database e selezionare Editor di query. Immettere la query seguente per creare una tabella denominata dbo.ToDo:

    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. Verificare che la funzione di Azure sia in grado di accedere al database SQL di Azure controllando le impostazioni del firewall del server. Passare al pannello del server nel portale di Azure e in Sicurezza selezionare Rete. L'eccezione per Consentire ai servizi e alle risorse di Azure di accedere a questo server deve essere verificata.

    Screenshot del controllo delle impostazioni del firewall database SQL di Azure nel portale di Azure.

Aggiornare le impostazioni dell'app per le funzioni

Nell'articolo di avvio rapido precedente è stata creata un'app per le funzioni in Azure. In questo articolo si aggiorna l'app per scrivere i dati nel database SQL di Azure appena creato. Per connettersi al database SQL di Azure, è necessario aggiungerlo stringa di connessione alle impostazioni dell'app. È quindi possibile scaricare la nuova impostazione nel file local.settings.json in modo da potersi connettere al database SQL di Azure durante l'esecuzione in locale.

  1. Modificare il stringa di connessione nel documento temporaneo creato in precedenza. Sostituire il valore di Password con la password usata durante la creazione del database SQL di Azure. Copiare il stringa di connessione aggiornato.

  2. Premere CTRL/CMD+MAIUSC+P per aprire il riquadro comandi, quindi cercare ed eseguire il comando Azure Functions: Add New Setting....

  3. Scegliere l'app per le funzioni creata nell'articolo precedente. Quando richiesto, immettere le informazioni seguenti:

    Richiesta Selezione
    Immettere il nome della nuova impostazione dell'app Digitare SqlConnectionString.
    Immettere il valore per "Sql Connessione ionString" Incollare il stringa di connessione del database SQL di Azure appena copiato.

    Verrà creata un'impostazione dell'applicazione denominata connection SqlConnectionString nell'app per le funzioni in Azure. È ora possibile scaricare questa impostazione nel file di local.settings.json.

  4. Premere di nuovo CTRL/CMD+MAIUSC+P per aprire il riquadro comandi, quindi cercare ed eseguire il comando Azure Functions: Download Remote Settings....

  5. Scegliere l'app per le funzioni creata nell'articolo precedente. Selezionare Sì per tutti per sovrascrivere le impostazioni locali esistenti.

Questa impostazione scarica tutte le impostazioni da Azure al progetto locale, inclusa la nuova impostazione di stringa di connessione. La maggior parte delle impostazioni scaricate non viene usata durante l'esecuzione in locale.

Registrare le estensioni delle associazioni

Poiché si usa un'associazione di output SQL di Azure, è necessario che l'estensione binding corrispondente sia installata prima di eseguire il progetto.

Ad eccezione dei trigger HTTP e timer, i binding vengono implementati come pacchetti di estensione. Eseguire il comando dotnet add package seguente nella finestra Terminale per aggiungere il pacchetto di estensione SQL di Azure al progetto.

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

Il progetto è stato configurato per l'uso di bundle di estensione, che installano automaticamente un set predefinito di pacchetti di estensione.

I bundle di estensione vengono abilitati nella radice del progetto in un file host.json come il seguente:

{
  "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
  }
}

:::

È ora possibile aggiungere il binding di output SQL di Azure al progetto.

Aggiungere un binding di output

In Funzioni ogni tipo di binding richiede di definire direction, type e un valore univoco name nel file function.json. Il modo in cui si definiscono questi attributi dipende dal linguaggio dell'app per le funzioni.

Aprire il file di progetto HttpExample.cs e aggiungere la classe seguente ToDoItem , che definisce l'oggetto scritto nel database:

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 un progetto di libreria di classi C# i binding vengono definiti come attributi di binding nel metodo della funzione. Il file function.json richiesto da Funzioni viene quindi generato automaticamente in base a questi attributi.

Aprire il file di progetto HttpExample.cs e aggiungere la classe di tipo di output seguente, che definisce gli oggetti combinati che verranno restituiti dalla funzione per la risposta HTTP e l'output SQL:

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

Aggiungere un'istruzione using alla Microsoft.Azure.Functions.Worker.Extensions.Sql libreria all'inizio del file:

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

Gli attributi di associazione vengono definiti direttamente nel codice. La configurazione dell'output sql di Azure descrive i campi necessari per un'associazione di output SQL di Azure.

Per questo MultiResponse scenario, è necessario aggiungere un'associazione extraOutputs di output alla funzione.

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

Aggiungere le proprietà seguenti alla configurazione dell'associazione:

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

Gli attributi di associazione vengono definiti direttamente nel file function_app.py . Usare l'elemento generic_output_binding Decorator per aggiungere un'associazione di output SQL di Azure:

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

In questo codice, arg_name identifica il parametro di associazione a cui si fa riferimento nel codice, type indica che l'associazione di output è un'associazione di output SQL, CommandText è la tabella in cui scrive l'associazione e ConnectionStringSetting è il nome di un'impostazione dell'applicazione che contiene il stringa di connessione SQL di Azure. Il stringa di connessione si trova nell'impostazione Sql Connessione ionString nel file local.settings.json.

Aggiungere il codice che usa l'associazione di output

Sostituire il metodo Run esistente con il codice seguente:

[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
    };
}

Aggiungere codice che usa l'oggetto di extraInputs associazione di output su context per inviare un documento JSON alla funzione di associazione di output denominata , sendToSql. Aggiungere questo codice prima dell'istruzione return.

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

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

Per usare il crypto modulo, aggiungere la riga seguente all'inizio del file:

const crypto = require("crypto");

A questo punto, la funzione sarà come indicato di seguito:

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' };
    }
  },
});

Aggiornare HttpExample\function_app.py in modo che corrisponda al codice seguente. Aggiungere il toDoItems parametro alla definizione della funzione e toDoItems.set() nell'istruzione if name: :

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
                )

Eseguire la funzione in locale

Visual Studio Code si integra con Azure Functions Core Tools per consentire l'esecuzione di questo progetto nel computer di sviluppo locale prima della pubblicazione in Azure. Se Core Tools non è già installato in locale, viene richiesto di installarlo la prima volta che si esegue il progetto.

  1. Per chiamare la funzione, premere F5 per avviare il progetto di app per le funzioni. Il pannello Terminale visualizza l'output di Core Tools. L'app viene avviata nel pannello Terminale. È possibile visualizzare l'endpoint dell'URL della funzione attivata da HTTP eseguita in locale.

    Screenshot dell'output di Visual Studio Code per la funzione locale.

    Se Core Tools non è già installato, selezionare Installa per installare Core Tools quando richiesto.
    In caso di problemi con l'esecuzione in Windows, assicurarsi che il terminale predefinito per Visual Studio Code non sia impostato su WSL Bash.

  2. Con Gli strumenti di base in esecuzione passare all'area Azure: Funzioni . In Funzioni espandere Progetto locale>Funzioni. Fare clic con il pulsante destro del mouse (Windows) o CTRL - (macOS) sulla funzione HttpExample e scegliere Execute Function Now... (Esegui funzione adesso).

    Screenshot della funzione execute now da Visual Studio Code.

  3. Nel corpo della richiesta INVIO premere INVIO per inviare un messaggio di richiesta alla funzione.

  4. Quando la funzione viene eseguita in locale e restituisce una risposta, viene generata una notifica in Visual Studio Code. Le informazioni sull'esecuzione della funzione vengono visualizzate nel pannello Terminale .

  5. Premere CTRL+C per arrestare Core Tools e disconnettere il debugger.

Eseguire la funzione in locale

  1. Come nell'articolo precedente, premere F5 per avviare il progetto dell'app per le funzioni e Core Tools.

  2. Con Core Tools in esecuzione, passare all'area Azure: Funzioni. In Funzioni espandere Progetto locale>Funzioni. Fare clic con il pulsante destro del mouse (ctrl+clic su Mac) sulla HttpExample funzione e scegliere Esegui funzione ora....

    Screenshot della voce di menu Execute function now (Esegui funzione) da Visual Studio Code.

  3. In Immettere il corpo della richiesta viene visualizzato il valore { "name": "Azure" } del corpo del messaggio di richiesta. Premere INVIO per inviare il messaggio di richiesta alla funzione.

  4. Dopo la restituzione di una risposta, premere CTRL+C per arrestare Core Tools.

Verificare che le informazioni siano state scritte nel database

  1. Nella portale di Azure tornare al database SQL di Azure e selezionare Editor di query.

    Screenshot dell'accesso all'editor di query nel portale di Azure.

  2. Connessione al database ed espandere Nodo Tabelle in Esplora oggetti a sinistra. Fare clic con il pulsante destro del mouse sulla dbo.ToDo tabella e selezionare Seleziona prime 1000 righe.

  3. Verificare che le nuove informazioni siano state scritte nel database dall'associazione di output.

Ridistribuire e verificare l'app aggiornata

  1. In Visual Studio Code premere F1 per aprire il riquadro comandi. Nel riquadro comandi cercare e selezionare Azure Functions: Deploy to function app....

  2. Scegliere l'app per le funzioni creata nel primo articolo. Poiché il progetto viene ridistribuito nella stessa app, selezionare Distribuisci per ignorare l'avviso sulla sovrascrittura di file.

  3. Al termine della distribuzione, è possibile usare di nuovo la funzionalità Esegui funzione ora per attivare la funzione in Azure.

  4. Controllare di nuovo i dati scritti nel database SQL di Azure per verificare che l'associazione di output generi di nuovo un nuovo documento JSON.

Pulire le risorse

In Azure il termine risorse si riferisce ad app per le funzioni, funzioni, account di archiviazione e così via. Le risorse sono raggruppate in gruppi di risorse, ed è possibile eliminare tutti gli elementi in un gruppo eliminando il gruppo.

Per completare queste guide introduttive sono state create risorse. Per tali risorse potrebbero venire addebitati costi, a seconda dello stato dell'account e dei prezzi dei servizi. Se le risorse non sono più necessarie, ecco come eliminarle:

  1. In Visual Studio Code premere F1 per aprire il riquadro comandi. Nel riquadro comandi cercare e selezionare Azure: Open in portal.

  2. Scegliere l'app per le funzioni e premere INVIO. La pagina dell'app per le funzioni viene aperta nel portale di Azure.

  3. Nella scheda Panoramica selezionare il collegamento accanto a Gruppo di risorse.

    Screenshot della selezione del gruppo di risorse da eliminare dalla pagina dell'app per le funzioni.

  4. Nella pagina Gruppo di risorse esaminare l'elenco delle risorse incluse e verificare che siano quelle da eliminare.

  5. Selezionare Elimina gruppo di risorse e seguire le istruzioni.

    L'eliminazione potrebbe richiedere alcuni minuti. Al termine, viene visualizzata una notifica per pochi secondi. È anche possibile selezionare l'icona a forma di campana nella parte superiore della pagina per visualizzare la notifica.

Passaggi successivi

La funzione attivata da HTTP è stata aggiornata per scrivere dati in database SQL di Azure. A questo punto, è possibile ottenere maggiori informazioni sullo sviluppo di funzioni con Visual Studio Code: