DEV Community

Cover image for Seeding your database with Prisma ORM
ishan
ishan

Posted on • Edited on

Seeding your database with Prisma ORM

Object Relation Mapper(ORM) is a technique of storing, retrieving, updating and deleting data from the database. ORMs let us define our models as classes that map to tables in a database.

When it comes to ORM there are many choices available to us like Sequelize, TypeORM, Knex, Drizzle and Prisma.

In this article we will cover Prisma, which is a top tier choice for ORM in your next application.

Prisma is an open source next-generation Node.js and TypeScript ORM. It describes itself as a β€œnext-generation ORM” that makes working with databases easy for application developers.

It's is written in Typescript, which leads us to type-safe database schemas. Of course, everything needs to be well set to define what that database will look like. It abstracts developers from writing database queries, thus ensuring we write safe database access schemas.

The most awesome thing is the Prisma-client to set up and write database, model data, data validation, and describe the relationships between different data fields. Not only that it has a migration tool and a supercool GUI to visualize your data.

Tools provided out of the box:

Prisma Client: Auto-generated and type-safe Prisma query builder

Prisma Migrate: Migration system

Prisma Studio: A modern GUI for browsing and managing data in your database

Connect Prisma with DB

We will follow the documentation to get started with Prisma. You can read and also take a reference to the documentation.

For a demo we are using Prisma along with Typescript in our sample Node project connect with MongoDB instance in Railway.

We need a database connection string, we will get a MongoDB database connection URL from Railway here.

npx prisma init --datasource-provider mongodb
Enter fullscreen mode Exit fullscreen mode

We will set the url field of the datasource block in our prisma schema to our recently created database connection URL.

Set, the url is set via an environment variable which is defined in .env:

DATABASE_URL="******"
Enter fullscreen mode Exit fullscreen mode

Modeling data

We can start with modelling our data for our application. Prisma schema provides an intuitive way to model data. Add the following models to your schema.prisma


// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mongodb"
  url      = env("DATABASE_URL")
}

model User {
  id            String    @id @default(auto()) @map("_id") @db.ObjectId
  name          String?
  image         String
  company       String
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt
  email         String    @unique
  emailVerified DateTime?
  password      String
}

model Products {
  id          String   @id @default(auto()) @map("_id") @db.ObjectId
  title       String   @unique
  description String
  price       String
  size        String
  quantity    Int
  image       String
  createdAt   DateTime @default(now())
}

enum Role {
  User
  Admin
  Buyer
  Seller
}

Enter fullscreen mode Exit fullscreen mode

We created our data model.

We are building something like a marketplace where users can upload list of products to the Marketplace. And there are list of products which we want to seed the DB with along with the new user created.

We need to run the two commands so that we can setup the documents and tables needed for our application.

npx prisma generate
Enter fullscreen mode Exit fullscreen mode

This command will generate the needed tables to store our data for our application using the data model we defined.

npx prisma studio
Enter fullscreen mode Exit fullscreen mode

This will spin a GUI where we can take a look into when we have the tables and/or data inserted into our DB.

Adding Fake data

Before starting seeding our database we need some fake data. To generate some decent realistic fake data we are using two libraries.

Lets install them both.

npm i @ngneat/falso @faker-js/faker 
Enter fullscreen mode Exit fullscreen mode

We will also install a library to hash the fake user password that is created.

@types/bcryptjs bcryptjs
Enter fullscreen mode Exit fullscreen mode

Let's create a new file and name it seed.ts

import bcrypt from 'bcryptjs';
import { randBetweenDate, randNumber, randProduct } from "@ngneat/falso";
import { faker } from "@faker-js/faker";
import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

const main = async () => {
  try{
    await prisma.products.deleteMany();
    const email = faker.internet.email('ishan', 'manandhar', 'example.fakerjs.dev');
    const companyName = faker.company.companyName()
    const hashedPassword = await bcrypt.hash('my_secure_password', 10);
    await prisma.products.deleteMany(); //delete existing products
    const fakeProducts = randProduct({
      length: 300,
    });

    // cleanup the existing database
    await prisma.user.delete({ where: { email } }).catch(() => {
      // delete existing user found with same email
    });

    await prisma.user.create({
      data: {
        name: 'ishan',
        image: '',
        email: email,
        password: hashedPassword,
        company: companyName
      },
    });

    for (let index = 0; index < fakeProducts.length; index++) {
      const product = fakeProducts[index];
      const name = faker.commerce.productName();
      await prisma.products.upsert({
        where: {
          title: name,
        },
        create: {
          title: name,
          description: faker.lorem.paragraph() || product?.description,
          price: faker.commerce.price(),
          image: faker.image.abstract(640, 480, true),
          quantity: randNumber({ min: 10, max: 100 }),
          size: faker.random.numeric(),
          createdAt: randBetweenDate({
            from: new Date("10/07/2020"),
            to: new Date(),
          }),
        },
        update: {},
      });
    }
    console.log(`Database has been seeded. 🌱`);
  }
  catch(error){
    throw error;
  }
}

main().catch((err) => {
  console.warn("Error While generating Seed: \n", err);
});
Enter fullscreen mode Exit fullscreen mode

Lets run the seed file with the command

npx prisma db seed
Enter fullscreen mode Exit fullscreen mode

After sucessfully running the seed file we can head to our terminal and run npx prisma studio to see our data added to our documents.

Yes, we have done it!

Conclusion

Prisma is such an awesome ORM that has a best developer experience(DX), documentation, observability support and end-to-end TypeScript coverage we can ever get.

It has made working with databases feel so intuitive and straightforward from the data modeling, running, migrations, writing the queries, and integrating it with the API's.

You can learn more from the Prisma official docs here.

Happy Coding!

Top comments (0)