Database-migraties zijn wijzigingen die aan een database worden aangebracht. Deze wijzigingen kunnen het wijzigen van het schema van een tabel, het bijwerken van gegevens in een reeks records, het toevoegen van gegevens of het verwijderen van een reeks records omvatten.

Database-migraties worden meestal uitgevoerd voordat een applicatie wordt gestart en worden niet succesvol meer dan eenmaal voor dezelfde database uitgevoerd. Database-migratietools bewaren een geschiedenis van migraties die in een database zijn uitgevoerd, zodat ze voor toekomstige doeleinden kunnen worden gevolgd.

In dit artikel leer je hoe je database-migraties kunt opzetten en uitvoeren in een minimale Node.js API-toepassing. We zullen ts-migrate-mongoose en een npm-script gebruiken om een migratie te maken en gegevens in een MongoDB-database te seed. ts-migrate-mongoose ondersteunt het uitvoeren van migratiescripts vanuit TypeScript-code en CommonJS-code.

ts-migrate-mongoose is een migratiekader voor Node.js-projecten die mongoose gebruiken als object-data-mapper. Het biedt een sjabloon voor het schrijven van migratiescripts. Het biedt ook een configuratie om de scripts programmatisch en vanuit de CLI uit te voeren.

Inhoudsopgave

Hoe het project in te stellen

Om ts-migrate-mongoose te gebruiken voor database migraties, moet je het volgende hebben:

  1. Een Node.js-project met mongoose geïnstalleerd als afhankelijkheid.

  2. Een MongoDB-database verbonden met het project.

  3. MongoDB Compass (Optioneel – om ons in staat te stellen de wijzigingen in de database te bekijken).

Een startrepository die kan worden gekloond van ts-migrate-mongoose-starter-repo is aangemaakt voor het gemak. Kloon de repository, vul de omgevingsvariabelen in en start de applicatie door het npm start commando uit te voeren.

Bezoek http://localhost:8000 met een browser of een API-client zoals Postman en de server zal een “Hallo daar!” tekst retourneren om aan te tonen dat de startapplicatie naar verwachting werkt.

Hoe ts-migrate-mongoose configureren voor het project

Om ts-migrate-mongoose te configureren voor het project, installeer ts-migrate-mongoose met dit commando:

npm install ts-migrate-mongoose

ts-migrate-mongoose staat configuratie toe met een JSON-bestand, een TypeScript-bestand, een .env bestand of via de CLI. Het is raadzaam om een .env bestand te gebruiken omdat de inhoud van de configuratie een database wachtwoord kan bevatten en het niet juist is om dat blootgesteld te hebben aan het publiek. .env bestanden zijn meestal verborgen via .gitignore bestanden, dus ze zijn veiliger om te gebruiken. Dit project zal een .env bestand gebruiken voor de ts-migrate-mongoose configuratie.

Het bestand moet de volgende sleutels en waarden bevatten:

  • MIGRATE_MONGO_URI – de URI van de Mongo database. Het is hetzelfde als de database URL.

  • MIGRATE_MONGO_COLLECTION – de naam van de collectie (of tabel) waarin migraties moeten worden opgeslagen. De standaardwaarde is migraties, wat in dit project wordt gebruikt. ts-migrate-mongoose slaat migraties op in MongoDB.

  • MIGRATE_MIGRATIONS_PATH – het pad naar de map voor het opslaan en lezen van migratiescripts. De standaardwaarde is ./migraties, wat in dit project wordt gebruikt.

Hoe Gebruikersgegevens Inzaaien met ts-migrate-mongoose

We hebben met succes een project kunnen maken en eraan gekoppeld aan een Mongo database. Op dit punt willen we gebruikersgegevens in de database inzaaien. We moeten:

  1. Een gebruikerscollectie (of tabel) maken

  2. Gebruik ts-migrate-mongoose om een migratiescript te maken om gegevens in te zaaien

  3. Gebruik ts-migrate-mongoose om de migratie uit te voeren om de gebruikersgegevens in de database in te zaaien voordat de toepassing start

1. Maak een gebruikerscollectie met behulp van Mongoose

Mongoose-schema kan worden gebruikt om een gebruikerscollectie (of tabel) aan te maken. Gebruikersdocumenten (of records) zullen de volgende velden (of kolommen) bevatten: email, favouriteEmoji en yearOfBirth.

Om een Mongoose-schema voor de gebruikerscollectie aan te maken, maak een user.model.js bestand in de hoofdmap van het project met de volgende codefragment:

const mongoose = require("mongoose");

const userSchema = new mongoose.Schema(
  {
    email: {
      type: String,
      lowercase: true,
      required: true,
    },
    favouriteEmoji: {
      type: String,
      required: true,
    },
    yearOfBirth: {
      type: Number,
      required: true,
    },
  },
  {
    timestamps: true,
  }
);

module.exports.UserModel = mongoose.model("User", userSchema);

2. Maak een migratiescript met ts-migrate-mongoose

ts-migrate-mongoose biedt CLI-opdrachten die kunnen worden gebruikt om migratiescripts aan te maken.

Door npx migrate create <naam-van-script> uit te voeren in de hoofdmap van het project wordt er een script aangemaakt in de MIGRATE_MIGRATIONS_PATH map (./migrations in ons geval). <naam-van-script> is de naam die we willen dat het migratiescriptbestand krijgt wanneer het wordt aangemaakt.

Om een migratiescript aan te maken om gebruikersgegevens in te voeren, voer uit:

npx migrate create seed-users

De opdracht zal een bestand aanmaken in de ./migrations map met een naam in de vorm van –<tijdstempel>-seed-users.ts. Het bestand zal de volgende codefragmentinhoud hebben:

// Importeer hier je modellen

export async function up (): Promise<void> {
  // Schrijf hier de migratie
}

export async function down (): Promise<void> {
  // Schrijf hier de migratie
}

De functie up wordt gebruikt om de migratie uit te voeren. De functie down wordt gebruikt om ongedaan te maken wat de up functie uitvoert, indien nodig. In ons geval proberen we gebruikers in de database te plaatsen. De up functie bevat code om gebruikers in de database te plaatsen en de down functie bevat code om gebruikers te verwijderen die zijn aangemaakt in de up functie.

Als de database wordt geïnspecteerd met MongoDB Compass, zal de migratiecollectie een document hebben dat er als volgt uitziet:

{
  "_id": ObjectId("6744740465519c3bd9c1a7d1"),
  "name": "seed-users",
  "state": "down",
  "createdAt": 2024-11-25T12:56:36.316+00:00,
  "updatedAt": 2024-11-25T12:56:36.316+00:00,
  "__v": 0
}

Het veld state van het migratiedocument is ingesteld op down. Na een succesvolle uitvoering verandert dit naar up.

U kunt de code in ./migrations/<timestamp>-seed-users.ts bijwerken naar die in het onderstaande fragment:

require("dotenv").config() // laad omgevingsvariabelen
const db = require("../db.js")
const { UserModel } = require("../user.model.js");

const seedUsers = [
  { email: "[email protected]", favouriteEmoji: "🏃", yearOfBirth: 1997 },
  { email: "[email protected]", favouriteEmoji: "🍏", yearOfBirth: 1998 },
];

export async function up (): Promise<void> {
  await db.connect(process.env.MONGO_URI)
  await UserModel.create(seedUsers);}

export async function down (): Promise<void> {
  await db.connect(process.env.MONGO_URI)
  await UserModel.delete({
    email: {
      $in: seedUsers.map((u) => u.email),
    },
  });
}

3. Voer de Migratie Uit Voordat de Applicatie Start

ts-migrate-mongoose biedt ons CLI-opdrachten om de up en down functie van migratiescripts uit te voeren.

Met npx migrate up <naam-van-script> kunnen we de up functie van een specifiek script uitvoeren. Met npx migrate up kunnen we de up functie van alle scripts in de ./migrations map uitvoeren met een state van down in de database.

Om de migratie uit te voeren voordat de toepassing start, maken we gebruik van npm-scripts. npm-scripts met een voorvoegsel van pre worden uitgevoerd vóór een script zonder het pre-voorvoegsel. Bijvoorbeeld, als er een dev-script en een predev-script zijn, zal telkens wanneer het dev-script wordt uitgevoerd met npm run dev, het predev-script automatisch worden uitgevoerd voordat het dev-script wordt uitgevoerd.

We zullen deze functie van npm-scripts gebruiken om het ts-migrate-mongoose commando in een prestart-script te plaatsen zodat de migratie wordt uitgevoerd voordat het start-script wordt uitgevoerd.

Update het package.json-bestand zodat er een prestart-script is dat het ts-migrate-mongoose commando uitvoert voor het uitvoeren van de up-functie van migratiescripts in het project.

  "scripts": {
    "prestart": "npx migrate up",
    "start": "node index.js"
  },

Met deze opzet, wanneer npm run start wordt uitgevoerd om de toepassing te starten, zal het prestart-script worden uitgevoerd om de migratie uit te voeren met behulp van ts-migrate-mongoose en de database te vullen voordat de toepassing start.

Je zou na het uitvoeren van npm run start iets soortgelijks moeten hebben als het onderstaande fragment:

Synchronizing database with file system migrations...
MongoDB connection successful
up: 1732543529744-seed-users.ts 
All migrations finished successfully

> [email protected] start
> node index.js

MongoDB connection successful                      
Server listening on port 8000

Bekijk de seed-users branch van de repository om de huidige status van de codebase op dit punt in het artikel te zien.

Hoe je een API-eindpunt bouwt om gegevens op te halen die zijn ingezaaid

We kunnen een API-eindpunt bouwen om de ingezaaide gebruikersgegevens in onze database op te halen. Update in het server.js-bestand de code naar die in het onderstaande fragment:

const { UserModel } = require("./user.model.js")

module.exports = async function (req, res) {
  const users = await UserModel.find({}) // haal alle gebruikers op in de database

  res.writeHead(200, { "Content-Type": "application/json" });
  return res.end(JSON.stringify({ // geef een JSON-weergave van de opgehaalde gebruikersgegevens
    users: users.map((u) => ({
      email: u.email,
      favouriteEmoji: u.favouriteEmoji,
      yearOfBirth: u.yearOfBirth,
      createdAt: u.createdAt
    }))
  }, null, 2));
};

Als we de toepassing starten en http://localhost:8000 bezoeken met behulp van Postman of een browser, krijgen we een JSON-reactie vergelijkbaar met degene hieronder:

{
  "users": [
    {
      "email": "[email protected]",
      "favouriteEmoji": "🏃",
      "yearOfBirth": 1997,
      "createdAt": "2024-11-25T14:18:55.416Z"
    },
    {
      "email": "[email protected]",
      "favouriteEmoji": "🍏",
      "yearOfBirth": 1998,
      "createdAt": "2024-11-25T14:18:55.416Z"
    }
  ]
}

Let op dat als de toepassing opnieuw wordt gestart, het migratiescript niet meer wordt uitgevoerd omdat de status van de migratie nu up zal zijn nadat het succesvol is uitgevoerd.

Bekijk de fetch-users branch van de repository om de huidige status van de codebase op dit punt in het artikel te zien.

Conclusie

Migraties zijn handig bij het bouwen van toepassingen en er is behoefte aan het toevoegen van initiële gegevens voor testen, het toevoegen van administratieve gebruikers, het bijwerken van databaseschema door kolommen toe te voegen of te verwijderen en het bijwerken van de waarden van kolommen in veel records tegelijk.

ts-migrate-mongoose kan een kader bieden voor het uitvoeren van migraties voor uw Node.js-toepassingen als u Mongoose met MongoDB gebruikt.