Seeding your database with Prisma ORM
Tags: typescript, javascript, node, prisma
Published: 2023-03-03 13:51:01

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](https://www.prisma.io/), 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](https://www.prisma.io/docs/concepts/components/prisma-client): Auto-generated and type-safe Prisma query builder

[Prisma Migrate](https://www.prisma.io/docs/concepts/components/prisma-migrate): Migration system

[Prisma Studio](https://www.prisma.io/docs/concepts/components/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](https://www.prisma.io/docs).

> For a demo we are using Prisma along with Typescript in our sample Node project connect with MongoDB instance in [Railway](https://railway.app/).

We need a database connection string, we will get a MongoDB database connection URL from Railway [here](https://docs.railway.app/databases/mongodb). 

```bash
npx prisma init --datasource-provider mongodb
```

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:


```bash
DATABASE_URL="******"
```


##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


```typescript

// 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
}

```

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.

```shell
npx prisma generate
```

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

```shell
npx prisma studio
```
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.

```shell
npm i @ngneat/falso @faker-js/faker 
```

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

```
@types/bcryptjs bcryptjs
```

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


```typescript
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);
});
```

Lets run the seed file with the command

```shell
npx prisma db seed
```

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.](https://www.prisma.io/docs)

Happy Coding!