A new prisma directory has been created in the src directory. It contains the (empty) schema that will be used to generate the database and the migrations.
// This is your Prisma schema file,// learn more about it in the docs: https://pris.ly/d/prisma-schemageneratorclient{provider="prisma-client-js"}datasourcedb{provider="sqlite"// (1)!url="file:../../mediaplayer.db"// (2)!}
SQLite will be used for the database.
The database will be saved in your working directory.
Find the Handlebars Prisma.prisma extension in Visual Studio Code extensions.
Install the extension. Once installed, click on the little Manage gear () and select the Add to devcontainer.json. Your devcontainer.json should looks like that.
// See https://containers.dev/implementors/json_reference/ for configuration reference{"name":"Create a media player application project","build":{"dockerfile":"Dockerfile"},"remoteUser":"node","postCreateCommand":"./.devcontainer/npm-global-without-sudo.sh","customizations":{"vscode":{"extensions":["andrejunges.Handlebars","Prisma.prisma"]}}}
Update the src/prisma/schema.prisma Prisma schema to add the Slide model from the Slide type you defined in TypeScript. The new property id is the assignment of an ID to a slide.
// This is your Prisma schema file,// learn more about it in the docs: https://pris.ly/d/prisma-schemageneratorclient{provider="prisma-client-js"}datasourcedb{provider="sqlite"url="file:../../mediaplayer.db"}// Enums are not supported in SQLite.// https://www.prisma.io/docs/reference/database-reference/database-features#misc//// An issue is opened to add support for this.// https://github.com/prisma/prisma/issues/2219// enum MediaType {// IMAGE// VIDEO// }modelSlide{idString@id@default(uuid())// (1)!srcStringtypeString// Enums are not support in SQLitealtStringintervalInt?// (2)!@@map(name:"slides")// (3)!}
The ID of each slide is an UUID.
The interval is optional.
Name the table slides (instead of Slide) to follow SQL conventions.
Create the first database migration to create the Slide table¶
Create the first database migration.
A database migration is an SQL script that changes the database to be up-to-date with the new requirements.
// This is your Prisma schema file,// learn more about it in the docs: https://pris.ly/d/prisma-schemageneratorclient{provider="prisma-client-js"}datasourcedb{provider="sqlite"url="file:../../mediaplayer.db"}// Enums are not supported in SQLite.// https://www.prisma.io/docs/reference/database-reference/database-features#misc//// An issue is opened to add support for this.// https://github.com/prisma/prisma/issues/2219// enum MediaType {// IMAGE// VIDEO// }modelSlide{idString@id@default(uuid())slideshowIdString@map(name:"slideshow_id")// (1)!srcStringtypeString// Enums are not support in SQLitealtStringintervalInt?slideshowSlideshow@relation(fields:[slideshowId],references:[id])// (2)!@@map(name:"slides")}modelSlideshow{idString@id@default(uuid())slidesSlide[]// (3)!@@map(name:"slideshows")}
Add the foreign key and name it slideshow_id.
Add the relation to the Slideshow model.
The slides are an array of Slide models.
Create the second database migration to create the Slideshow table¶
/* Warnings: - Added the required column `slideshow_id` to the `slides` table without a default value. This is not possible if the table is not empty.*/-- CreateTableCREATETABLE"slideshows"("id"TEXTNOTNULLPRIMARYKEY);-- RedefineTablesPRAGMAforeign_keys=OFF;CREATETABLE"new_slides"("id"TEXTNOTNULLPRIMARYKEY,"slideshow_id"TEXTNOTNULL,"src"TEXTNOTNULL,"type"TEXTNOTNULL,"alt"TEXTNOTNULL,"interval"INTEGER,CONSTRAINT"slides_slideshow_id_fkey"FOREIGNKEY("slideshow_id")REFERENCES"slideshows"("id")ONDELETERESTRICTONUPDATECASCADE);INSERTINTO"new_slides"("alt","id","interval","src","type")SELECT"alt","id","interval","src","type"FROM"slides";DROPTABLE"slides";ALTERTABLE"new_slides"RENAMETO"slides";PRAGMAforeign_key_check;PRAGMAforeign_keys=ON;
It creates the tables slideshows and update the old slides tables with the new fields needed to create the relationship between the tables slideshows and slides.
Now that Prisma is available in the application, you can inject it anywhere using dependency injection as follow.
The Map made earlier is now removed as everything is saved in the database. The unnecessary imports are deleted and Prisma is used to access the database.
Warning
At this time of writing, the Prisma Extension seems to have problems to reload the TS server within the Dev Container as stated in this GitHub issue. You can manually reload the TS server with View > Command Palette... and execute TypeScript: Restart TS server to update the Prisma types if you have issues to see the right types.
Inject the PrismaService. Thanks to NestJS and the definition in the AppModule, the service is now available in your AppService. You can use the service with the this.prisma keyword.
As Prisma is asynchrone, the async keyword tells that the function is asynchrone as well.
The PrismaService is used to get the slideshows from the database.
We ask Prisma to include the slides from the slideshow as well. Without this, Prisma would only return the slideshows with their IDs but without the slides.
Define the WHERE condition. In this case, we ask Prisma to get the slideshow with the ID asked by the user.
Define the data of the slideshow to create. We omit the ID as Prisma will generate it for use and we set the slides from the user input.
Delete all the slides of the previous slideshow before creating a new slideshow with its new slides.
The suppression of the slideshow in the database throws an error instead of the boolean previously used.
# Run all the migrationsnpxprismamigratedev--namemediaplayer--schemasrc/prisma/schema.prisma
# Generate the clientnpxprismagenerate--schemasrc/prisma/schema.prisma
Start the application.
Create a slideshow.
Once done, stop your NestJS application with Ctrl+C in your terminal.
Restart your NestJS application.
Try to access the slideshows.
You should now see the slideshows are still there! They have been successfully persisted!
Migrations are really useful to keep up the databases updates during the development process. As migrations need to be created quite often, let's save the required commands in the package.json as new scripts.
You'll then be able to run the migration command with npm run prisma:migrate:dev and the generate command with npm run prisma:generate:dev!
Congrats! Your application now persists all the slideshows in the database.
Prisma speeds up the development of the database thanks to its schema and the migrations.
The Prisma client generated from the schema ensures the types of your inputs are correct thanks to TypeScript.
When restarting the application, there is no more data loss.
SQLite helps to develop simple applications as only a file is required to store the database. For more robust applications, another kind of database is recommended, such as PostgreSQL. However, for development, SQLite is perfectly fine.