Catégories
JavaScript Vue.js

Nuxt.js + Adonis.js / Chapitre 03 : Base de données (postgresql) et migrations

Au menu de ce chapitre : PostgreSQL & migrations

Dans ce nouvel article de notre série Nuxt.js + Adonis.js, nous allons plonger dans la gestion de la base de données et des migrations nécessaires pour y arriver. Afin de corser un peu le tout, nous allons sortir de notre zone de confort habituelle en remplaçant MySQL par PostgreSQL.

En somme, à la fin de ce chapitre vous serez un pro des commandes concernant les migrations via la ligne de commande 😉

Previously in « Nuxt.js + Adonis.js » 😀

Avant tout, sachez que dans le précédent article, nous avons mis en place l’architecture des templates nécessaires à notre application Meet The Coders.

Sommaire du tutoriel

Nous sommes partis, par contre, prenez un bon café, l’article sera un peu long !

Pour mieux se concentrer, travaillons en musique !

Perso, je me concentre beaucoup mieux lorsque j’écoute de la musique en travaillant et vous ?

Si c’est votre cas aussi, je vous propose de tester Amazon Music, le service est vraiment de qualité et il y en a pour tout les goûts musicaux.

Par souci de transparence, sachez que si vous faites l’essai gratuit 30 jours, je recevrai une commission qui m’aidera beaucoup et ne vous coûtera rien.
Si le service proposé par Amazon ne vous convenait pas, vous pouvez le résilier à tout moment avant la fin de la période d’essai.

Installer la base de données

Premièrement, nous allons installer notre base de données. Je travaille régulièrement avec MySQL, mais pour cet article, j’avais envie de mettre en place PostgreSQL.

Si vous développez sous Windows, je ne peux que vous recommander d’utiliser Laragon. L’avantage est qu’il permet notamment d’installer plusieurs bases de données très facilement ainsi que plusieurs versions différentes d’une même bases de données (en ayant toutefois la possibilité d’utiliser qu’une seule version à la fois).

Toutefois, si vous préférez installer PostgreSQL manuellement, je vous renvoie à la documentation officielle qui vous guidera pas à pas pour l’installer sur votre environnement.

Ainsi, une fois PostgreSQL installé, vous pourrez le lancer dans Laragon :

Lancement de PostgreSQL
Lancement de PostgreSQL

Pour cela, il vous suffit, comme sur l’image ci-dessus, de cliquer sur le menu de Laragon et de cliquer sur « Start PostgreSQL ».

PostgreSQL est a présent lancé
PostgreSQL est a présent lancé

Vous verrez alors PostgreSQL démarrer en utilisant le port 5432.

Lancer pgAdmin4 pour gérer votre base de données PostgreSQL

Laragon vous propose également d’accéder à un gestionnaire de base de données équivalent à PhpMyAdmin avec PgAdmin 4.

Lancement de PgAdmin 4, le gestionnaire graphique de base de données PostgreSQL
Lancement de PgAdmin 4, le gestionnaire graphique de base de données PostgreSQL

Cela lancera alors l’affichage dans votre navigateur préféré de l’interface pgadmin :

Interface phadmin4 pour gérer vos base de données PostgreSQL
Interface phadmin4 pour gérer vos base de données PostgreSQL

Configurer un utilisateur pour votre base de données

Il est toujours plus sécurisé de prendre l’habitude de se créer un utilisateur dédié à votre base de données que d’utiliser le super utilisateur et étant donné que l’on ne souhaite pas plaisanter avec la sécurité, c’est ce que nous allons faire de ce pas !

Nous allons donc créer un utilisateur ‘meetthecoders’ pour notre base de données ‘meettthecoders’. Original, non ?

Gestion des utilisateurs dans PostgreSQL
Gestion des utilisateurs dans PostgreSQL

En conséquence, dans l’interface pgadmin en cliquant droite sur « Login / Group Roles », choisissez « Create » et « Login/Group Role… »

Il suffit ensuite de remplir les champs demandés.

Gestion des utilisateurs dans PostgreSQL - détails
Gestion des utilisateurs dans PostgreSQL – détails

Afin que notre effort de sécurité ne soit pas vide de sens 😀 , n’oubliez pas de mettre en place un mot de passe pour l’utilisateur dans l’onglet ‘Definition’.

Gestion des utilisateurs dans PostgreSQL - détails
Gestion des utilisateurs dans PostgreSQL – détails

Il ne faut pas oublier non plus ensuite d’affecter cet utilisateur à votre base de données 😉 !

Installer Adonis.js en tant que serveur d’API

Etant donnée que Nuxt.js fait office de frontend, il nous faut un frontend et c’est là qu’entre en scène Adonis.js.

Nous allons l’installer et le configurer en tant que serveur.

Comme toujours l’idéal reste et restera toujours la documentation comme point de départ.

Ainsi, on s’installe l’outil cli qui nous permettra d’installer des applications adonis facilement.

npm i -g @adonisjs/cli

Ensuite, il suffit de lancer l’installation d’adonis via la commande suivante :

adonis new meetthecoders-server
L'installation d'Adonis.js en ligne de commande
L’installation d’Adonis.js en ligne de commande

Configurer Adonis.js pour travailler avec PostgreSQL

Ensuite afin qu’Adonis, puisse fonctionner avec notre moteur de base de données fraîchement installé, il faut installer ce dernier aux yeux d’Adonis, comme l’indique la documentation.

Cela s’effectue donc en deux étapes, voire une si vous avez la même chance que moi.

Installation du driver postgreSQL

Tout d’abord, la première consiste à installer le driver de PostgreSQL via npm :

npm i pg
Installation du module npm pg (PostgreSQL)
Installation du module npm pg (PostgreSQL)

Vérification des providers

La deuxième étape est de vérifier que le database provider (Lucid) est bien installé et configuré. Pour cela on vérifie que les providers suivants sont bien enregistrés dans start/app.js :

const providers = [
  '@adonisjs/lucid/providers/LucidProvider'
]

const aceProviders = [
  '@adonisjs/lucid/providers/MigrationsProvider'
]

Si ce n’est pas le cas, il sera nécessaire d’installer le paquet @adonisjs/lucid.

adonis install @adonisjs/lucid

Normalement, vous ne devriez pas avoir à réaliser cette deuxième étape, car lors de l’installation d’Adonis.js, l’ORM Lucid a déjà été installé.

En tout cas, c’était le cas chez moi, un petit
ls -la node_modules\@adonisjs\lucid
nous montre que le répertoire est bien présent et que les fichiers de l’ORM sont bien présents.

Lors de l’installation d’Adonis.js, l’ORM Lucid est normalement installé

Enfin en ligne de commande

nano start/app.js

nous montre que les providers de Lucid sont bien présents. Nous sommes donc prêts pour l’étape suivante.

L'ORM Lucid est déjà installé après l'installation d'Adonis.js via Nuxt.js
L’ORM Lucid est déjà installé après l’installation d’Adonis.js via Nuxt.js

Configurer PostgreSQL comme base de données par défaut

Il est tout d’abord nécessaire d’indiquer à Adonis.js que la base de données qui devra être utilisée par défaut sera une base postgreSQL.

C’est dans ce but que nous modifions le fichier config/database.js comme suit en remplaçant la connexion par défaut au moteur sqlite par la connexion au moteur postgreSQL :

module.exports = {
  /*
  |--------------------------------------------------------------------------
  | Default Connection
  |--------------------------------------------------------------------------
  |
  | Connection defines the default connection settings to be used while
  | interacting with SQL databases.
  |
  */
  connection: Env.get('DB_CONNECTION', 'pg'),

Configurer votre fichier .env pour connecter votre base de données

Ensuite, dans le fichier .env qui se trouve à la racine de notre projet, modifiez ce contenu

DB_CONNECTION=sqlite
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=root
DB_PASSWORD=
DB_DATABASE=adonis

Par celui-ci :

DB_CONNECTION=pg
DB_HOST=127.0.0.1
DB_PORT=5432
DB_USER=meetthecoders
DB_PASSWORD=monSuperMotDePasseSécurisé!3
DB_DATABASE=meetthecoders

Migrations

Lors de l’installation du projet Adonis.js le dossier database\migrations comprends les migrations user et token.

Les fichiers de migrations manquant que nous allons récupérer
Les fichiers de migrations user et token

Fichier de migration user.js

Je vous partage ci-dessous le code du fichier de migration user.js.

'use strict'

/** @type {import('@adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')

class UserSchema extends Schema {
  up () {
    this.create('users', (table) => {
      table.increments()
      table.string('username', 80).notNullable().unique()
      table.string('email', 254).notNullable().unique()
      table.string('password', 60).notNullable()
      table.timestamps()
    })
  }

  down () {
    this.drop('users')
  }
}

module.exports = UserSchema

Fichier de migration token.js

Idem pour le fichier token.js.

'use strict'

/** @type {import('@adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')

class TokensSchema extends Schema {
  up () {
    this.create('tokens', (table) => {
      table.increments()
      table.integer('user_id').unsigned().references('id').inTable('users')
      table.string('token', 255).notNullable().unique().index()
      table.string('type', 80).notNullable()
      table.boolean('is_revoked').defaultTo(false)
      table.timestamps()
    })
  }

  down () {
    this.drop('tokens')
  }
}

module.exports = TokensSchema

Lancement de la migration dans PostgreSQL

Nous allons à nouveau nous servir de la ligne de commande. L’utilitaire cli d’Adonis.js est vraiment proche de ce que propose Laravel avec Artisan. Pour les connaisseurs de Laravel, ils ne seront donc pas dépaysés !

> adonis migration:run

Si tout se passe comme prévu,

"J'adore quand un plan se déroule sans accroc !"
« J’adore quand un plan se déroule sans accroc ! »

vous devriez obtenir ce résultat :

Lancement des migrations initiales créant nos premières tables dans PostgreSQL
Lancement des migrations initiales créant nos premières tables dans PostgreSQL

Vous pouvez alors vérifier dans PostgreSQL que vos tables ont bien étés créées.

Les tables ont bien été crées dans PostgreSQL, tout va bien !
Les tables ont bien été crées dans PostgreSQL, tout va bien !

La table adonis_schema garde la trace des migrations effectuées et vous permet de vous donner les renseignements nécessaires lorsque vous lancez un

> adonis migration:status
Etat des migrations de notre application
Etat des migrations de notre application

Création d’une migration pour nos « coders »

Nous allons nous servir de la table users que nous venons de créer pour lui rajouter les champs qui nous serons nécessaires :

  • latitude
  • longitude

à cette fin, nous lançons la commande suivante :

> adonis make:migration add_coders_fields_to_users_table

Lorsque Adonis.js vous demande si vous voulez créer (‘Create table’) ou sélectionner la table (‘Select table’), choisissez ‘Select table’.

Modification de la table users dans notre base de données PostgreSQL
Modification de la table users dans notre base de données PostgreSQL

Nous allons ensuite éditer notre fichier de migration ‘1565014380271_add_coders_fields_to_users_schema.js‘ qui vient d’apparaître dans le dossier database/migrations.

Voici le contenu du fichier généré :

'use strict'

/** @type {import('@adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')

class AddCodersFieldsToUsersSchema extends Schema {
  up () {
    this.table('add_coders_fields_to_users', (table) => {
      // alter table
    })
  }

  down () {
    this.table('add_coders_fields_to_users', (table) => {
      // reverse alternations
    })
  }
}

module.exports = AddCodersFieldsToUsersSchema

Nous allons le modifier par le code suivant :

'use strict'

/** @type {import('@adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')

class AddCodersFieldsToUsersSchema extends Schema {
  up () {
    this.alter('users', (table) => {
      // alter table
      table.decimal('latitude', null).nullable()
      table.decimal('longitude', null).nullable()
    })
  }

  down () {
    this.table('users', (table) => {
      // reverse alternations
      table.dropColumns('latitude', 'longitude')
    })
  }
}

module.exports = AddCodersFieldsToUsersSchema

Vous avez très certainement relevé la présence de ‘null’ comme second paramètre de la définition de nos champs latitude et longitude, n’est ce pas ?

Si on se rends sur la documentation correspondante (RTFM) de Knex.js, on nous y explique que le fait de passer null comme second argument de la fonction decimal permet de stocker n’importe quel nombre décimal avec n’importe quelle précision, cela est relativement pratique et nous permet de ne pas trop réfléchir à la mise en place 😉

Il n’y a plus ensuite qu’à lancer la migration :

> adonis migration:run

N’hésitez pas à lancer un rollback pour vérifier que la migration est réversible.

> adonis migration:rollback

Si tout est ok au niveau de votre base de données, vous pouvez lancer à nouveau la migration. C’est une bonne habitude de vérifier la réversibilité de vos migrations. Cela permet de pouvoir revenir en arrière autant que l’on veut dans les migrations.

Création d’une nouvelle table ‘Languages’ dans notre base de données PostgreSQL

Notre but

À présent que nous avons ajouté les champs nécessaires à notre table users (coders), nous avons besoin d’une structure nous permettant de coupler un utilisateur avec un ou plusieurs langages différents et en indiquant le niveau (skills) du coders pour ce langage.

Pour cela, nous aurons besoin d’une table ‘languages‘ et d’une table pivot ‘languages_users‘ qui effectuera la liaison entre un coder (table ‘users‘) et les languages qu’il maîtrise.

De plus, nous devrons pouvoir pour chaque couple coder/language de cette table pivot pouvoir associer le niveau de maîtrise de l’utilisateur.

Cela se complique un peu, mais ce n’est pas cela qui va nous faire peur, n’est ce pas ?

Nous utiliserons pour cela la relation belongs to many proposée dans la documentation ‘Relationships’ d’Adonis.js.

La table languages

Tout d’abord, nous allons créer notre migration pour créer la table ‘Languages’.

> adonis make:migration languages

Encore une fois, Adonis vous demande de choisir entre créer la table ou la sélectionner. Cette fois-ci il sera nécessaire de créer la table, car elle n’existe pas.

Choisissez 'Create table' dans la sélection qui vous est proposée
Choisissez ‘Create table’ dans la sélection qui vous est proposée
L'opération de création de migration a réussie
L’opération de création de migration a réussie

À présent, vous pouvez aller compléter le fichier de migration qui vient d’être créée dans le répertoire database/migrations.

'use strict'

/** @type {import('@adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')

class LanguagesSchema extends Schema {
  up () {
    this.create('languages', (table) => {
      table.increments()
      table.string('title')
      table.string('link')
      table.string('description')
      table.timestamps()
    })
  }

  down () {
    this.drop('languages')
  }
}

module.exports = LanguagesSchema

Nous reprenons les mêmes champs que pour la table Jobs de l’article original de Gary Simon car il s’applique très bien à notre contexte.

Nous pouvons, à présent, lancer la migration et vérifier que la table est bien créée dans notre base de données PostgreSQL.

 Lancement de la migration pour la table 'languages' dans notre base de données PostgreSQL
Lancement de la migration pour la table ‘languages’ dans notre base de données PostgreSQL
La table 'languages' est bien créée dans notre base PostgreSQL 'meetthecoders'
La table ‘languages’ est bien créée dans notre base PostgreSQL ‘meetthecoders’

Nous pouvons à présent nous préoccuper de la relation belongs to many.

À cette fin, la documentation indique qu’il est nécessaire de créer la table pivot via le système de migrations. C’est ce que nous allons voir à présent.

Création de la table pivot languages_users dans la base de données PostgreSQL

Nous créons à présent la table language_users via la ligne de commande. Nous respectons le standard des créations de table pivot qui veut que l’on prenne le nom au singulier de chaque table, placé dans l’ordre alphabétique et séparés par un underscore (‘_’) . Ici ce sera donc ‘language_users‘ qui nous servira de nom pour notre table pivot.

adonis make:migration language_user

et nous choisissons l’option create puisque cette table n’existe pas encore.

A vous de remplacer le code généré par celui ci-dessous :

'use strict'

/** @type {import('@adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')

class LanguageUserSchema extends Schema {
  up () {
    this.create('language_users', (table) => {
      table.primary(['id', 'language_id', 'user_id'])
      table.integer('id').notNullable().unsigned()
      table.integer('language_id').notNullable().unsigned()
      table.integer('user_id').notNullable().unsigned()
      table.integer('level').notNullable().defaultTo(0)
      table.timestamps()
    })
  }

  down () {
    this.drop('language_users')
  }
}

module.exports = LanguageUserSchema

A noter :

  • il n’est pas possible d’utiliser table.increments(), il faut nécessairement utiliser table.integer(‘id’)
  • vous devez déclarer toutes les clés primaires via l’instruction table.primary

Enfin, il reste bien évidemment à lancer la migration avec la commande que vous maîtrisez à présent :

> adonis migration:run

Conclusion

Voilà, nous en avons terminé pour cette partie sur l’implémentation de la base de données et des migrations nécessaires.

Dans ce chapitre, vous vous êtes familiarisés avec la commande en ligne de commande adonis, sur la partie migration. Ainsi, nous avons vu :

  • adonis migration:status : qui vous permet de visualiser le statut des migrations et notamment de voir lesquelles ont étés effectuées
  • adonis migration:run : qui lance proprement dit l’exécution de la migration et crée concrètement la table dans PostgreSQL
  • adonis migration:rollback : commande qui nous offre la possibilité d’annuler la dernière migration et d’éventuellement corriger un script
  • adonis create:migration : qui permet d’initier un fichier de migration en création ou en modification de table déjà existante

Dès maintenant, je vous donne rendez-vous dans le prochain chapitre, qui parlera des modèles associés à nos tables.

D’ores et déjà, je vous invite à laisser vos commentaires pour toute demande d’amélioration de l’article, pour me signaler d’éventuelles erreurs ou fautes typographiques.

Enfin, j’allais oublier, vous pourrez retrouver les ressources de ce tutoriel sur notre GitHub dédié au backend du projet Meet The Coders

Aidez nous à nous améliorer en évaluant cet article :
[Total: 0 Moyenne: 0]

Par HappyToDev

Absolument passionné depuis toujours par l'informatique et la programmation, je souhaite via ce blog vous faire passer un peu du savoir que j'ai accumulé depuis des années.
Et même, pourquoi pas, vous aider à faire le premier pas dans le développement web.

Vous êtes prêts ?
Alors allons y ensemble et n'oubliez pas que les débutants sont vraiment les bienvenus.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.