Come accedere ad un database da una skill

Accedere ad un database da una skill di Alexa
Avatar Paolo Godino

Anche le skill più semplici possono aver bisogno di una piccola base di dati a cui fare riferimento. Nei casi più semplici può essere sufficiente un database con una sola tabella quindi senza relazioni, in altri casi può essere necessario un database relazionale, in altri ancora un database nosql.

Può bastare un semplice file JSON

Nei casi semplici può bastare un file JSON che di fatto può essere considerato un database non relazionale con una sola tabella. Questo è il caso del database delle caratteristiche dei segni zodiacali che utilizzo nello sviluppo della skill di esempio durante il corso.

Questo tipo di soluzione è da considerare quando il numero di elementi del database non è molto elevato (elementi dell’array) e le colonne della tabella non troppo numerose (elementi del dizionario di ogni singolo elemento).

Le funzioni messe a disposizione da javascript (ipotizziamo sempre di utilizzare Node.js come ambiente di esecuzione della skill di Alexa) sono molto potenti ed essenziali e quindi risulta abbastanza agevole l’interrogazione del nostro database. In un normale database ciò corrisponderebbe all’esecuzione delle query.

Facciamo un esempio con un semplice database in cui c’è un elenco dei frutti con il relativo colore.

const fruits = [
    {
        "id": 1,
        "name": "arancia",
        "color": "arancione"
    },
    {
        "id": 2,
        "name": "mela",
        "color": "rosso"
    },
    {
        "id": 3,
        "name": "mela",
        "color": “giallo”
    },
    {
        "id": 4,
        "name": "mela",
        "color": “verde”
    },
    {
        "id": 5,
        "name": "anguria",
        "color": "verde"
    }
];

Se desideriamo eseguire l’equivalente di questa quei SQL

SELECT * FROM fruits WHERE name == "mela";

Possiamo utilizzare il metodo filare in questo modo:

let res = fruits.filter(function(el) {
  return el.name === 'mela';
});
console.log(res);

Ottenendo l’array con gli elementi in cui name è pari a mela. Il metodo filter richiama infatti la funzione che riceve come argomento una volta per ogni elemento dell’array. La funzione riceve come parametro l’elemento dell’array (el nel caso dell’esempio) e deve ritornare true se l’elemento deve essere incluso nell’array restituito dal metodo filter.

Ricordo che la versione ECMA 2015 di javascript permette di scrivere una versione più compatta del codice sopra indicato mediante le Arrow functions:

let res = fruits.filter(el => el.name === "mela");
console.log(res);

La semantica è la stessa anche se espressa in modo molto più sintetico. Viene assegnato al parametro prima di => il valore di ogni elemento dell’array (el in questo caso) e viene restituito il risultato del confronto indicato a destra.

Nel caso in cui la quei venga realizzata su quella che chiameremmo chiave primaria del database o su elementi univoci possiamo utilizzare il metodo find che restituisce un singolo elemento. Nel caso in cui ci siamo più occorrenze viene restituita solo la prima.

let resFind1 = fruits.find(el => el.id === 4);
console.log(resFind1);

let resFind2 = fruits.find(el => el.name === "mela");
console.log(resFind2);

Puoi vedere in esecuzione il codice o provare a fare delle prove partendo dal mio repl: https://repl.it/@pgodino/JSON-database

Accesso ad un database relazionale mysql

L’accesso ad un database relazionale esterno può essere effettuato mediante gli strumenti offerti da Node.js. In particolare per quel che riguarda l’accesso ad un database mysql è possibile utilizzare il package mysql.

E’ possibile definire i parametri della connessione al server mysql:

let sqlConfig = {
    host: "<indirizzo del server>",
    user: "<utente>",
    password: "<password>",
    database: "<database>"
};

Immaginando che nella la tabella fruit abbia questa struttura:

idnamecolor
1aranciaarancione
2melarosso
3melagiallo
4melaverde
5anguriaverde

Con questa classe è possibile utilizzare il database in modo molto semplice con la logica delle promise javascript:

class Database {
    constructor( config ) {
        this.connection = mysql.createConnection( config );
    }
    query( sql, args ) {
        return new Promise( ( resolve, reject ) => {
            this.connection.query( sql, args, ( err, rows ) => {
                if ( err )
                    return reject( err );
                resolve( rows );
            } );
        } );
    }
    close() {
        return new Promise( ( resolve, reject ) => {
            this.connection.end( err => {
                if ( err )
                    return reject( err );
                resolve();
            } );
        } );
    }
}

Un esempio di utilizzo per la query vista in precedenza:

let database = new Database(sqlConfig);
return database.query( `SELECT * FROM fruits WHERE name "mela"` ).then( rows => {
  
     database.close();
                
     console.log(rows);
    
}); 

Il server mysql può essere indifferentemente ospitato su Amazon AWS o su un proprio server.

Utilizzo di database nosql

Nel caso in cui ci sia una mole di dati no strutturati come per esempio un insieme di elementi non omogenei a cui fare accesso con un meccanismo del tipo chiave valore la soluzione migliore potrebbe essere l’utilizzo di un database nosql. Amazon AWS offre DynamoDB come database non relazionale.

In tal caso rimando alla documentazione Amazon per l’utilizzo di DynamoDB in ambiente Node.js.

Tagged in :

Avatar Paolo Godino

Lascia un commento

More Articles & Posts