avatarTomas Svojanovsky

Summary

This tutorial demonstrates how to use Prisma seeds to populate a database with initial data in a Next.js application.

Abstract

In this tutorial, the author continues from a previous installment to explore the use of Prisma seeds in a Next.js application. The author explains the benefits of using seeds for data that is not user-related, such as currencies or languages, and guides the reader through the process of setting up the project structure, writing and running seeds using Prisma, and populating the database with initial data. The tutorial includes code examples and instructions for running the seeds using the command line.

Bullet points

  • Prisma seeds are a valuable tool for populating a database with initial data that is not user-related.
  • To use Prisma seeds in a Next.js application, the author recommends creating a db.ts file in a lib folder and setting up the project structure accordingly.
  • The author provides code examples for setting up the project structure, writing and running seeds using Prisma, and populating the database with initial data.
  • The tutorial includes instructions for running the seeds using the command line and demonstrates how to structure the project folders.
  • The author encourages readers to continue learning and exploring further enhancements for their Next.js applications.

Elevate Your Next.js App with Prisma: A Step-by-Step Tutorial (Part 2)

Welcome back to the second part of our tutorial series. In the previous installment, we delved into the foundational steps of integrating Prisma into your Next.js application.

Now, let’s continue our journey by exploring a powerful feature: seeds. Seeds are a valuable tool for populating your database with initial data.

I’ll guide you through the process, from setting up the project structure to writing and running seeds using Prisma. So, buckle up as we uncover the intricacies of leveraging Prisma in your Next.js app to ensure a seamless and efficient development experience.

Let’s continue where we left off. If you missed the previous part, you can read it here: Part 1.

Seeds

This is a cool feature. I used it for data that is not user-related, meaning data that cannot be directly created or updated from the app. For example, I have currencies or languages in the app, so I can repopulate the database. You can use it for various reasons.

Prisma

Start by creating a file db.ts in a lib folder. Create the lib folder in the root of the app.

import { PrismaClient } from "@prisma/client";

declare global {
    // eslint-disable-next-line no-var
    var cachedPrisma: PrismaClient;
}

let prisma: PrismaClient;
if (process.env.NODE_ENV === "production") {
    prisma = new PrismaClient();
} else {
    if (!global.cachedPrisma) {
        global.cachedPrisma = new PrismaClient();
    }
    prisma = global.cachedPrisma;
}

export const db = prisma;

Why is it so complicated, and why do we need it? It enables us to use Prisma in the seeds or in the app. The complexity arises because, in production, we can simply use prisma = new PrismaClient(). However, in development, with hot reloading, using it straightforwardly won't work properly.

Tsconfig

The next step is to add tsconfig-seed.json to the root of the app, specifically suited for the seeds.

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "incremental": true,
    "esModuleInterop": true,
    "module": "CommonJS",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "baseUrl": ".",
    "plugins": [
      {
        "name": "next"
      }
    ],
    "paths": {
      "@/components/*": [
        "./components/*"
      ],
      "@/hooks/*": [
        "./hooks/*"
      ],
      "@/lib/*": [
        "./lib/*"
      ],
      "@/styles/*": [
        "./src/styles/*"
      ],
      "@/prisma/*": [
        "./prisma/*"
      ],
      "@/assets/*": [
        "./assets/*"
      ]
    }
  },
  "include": [
    "next-env.d.ts",
    ".next/types/**/*.ts",
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

Also, we would like to run our seeds from the command line, so add this code to the package.json. Additionally, this involves installing ts-node if you don't have it already in your app.

"prisma": {
  "seed": "ts-node -P tsconfig-seed.json -r tsconfig-paths/register --transpileOnly prisma/seed.ts"
}
npm i -D ts-node

Code

We have everything set up; now we can write some seeds. Hooray! In the prisma folder, we need to create seed.ts because that's how we defined it in the package.json in the previous step.

You can place it somewhere else if you don't like it, but it is suitable to put it where you can find it easily.

Also, in the prisma folder, create a folder named seedData with a usersSeed.ts file.

// seed.ts

import { usersSeed } from "@/prisma/seedData/usersSeed";
import { db } from "@/lib/db";

async function main() {
    await usersSeed();
}

main()
    .then(async () => {
        await db.$disconnect();
    })
    .catch(async (e) => {
        console.error(e);
        await db.$disconnect();
        process.exit(1);
    });

We can import db (Prisma) and directly call user on it because we executed npx prisma generate. To get it fully working, we also need either npx prisma migrate dev or npx prisma db push. We used the first one to track the history of changes we made to the database. The second one can be used, for example, with Planetscale, where the history is preserved on their side.

// seedData/usersSeed.ts

import { db } from "@/lib/db";

const users = [
    {
        firstName: "Tomas",
        lastName: "Svojanovsky",
    },
    {
        firstName: "John",
        lastName: "Doe",
    },
];

export async function instrumentCategoriesSeed() {
    for (const { firstName, lastName } of users) {
        await db.user.create({
            data: {
                firstName,
                lastName,
            },
        });   
    }
}

In the model, we can use create or other methods that Prisma provides. For example, for fetching, there are methods like findMany, findFirst, and so on. The create method expects an object with a data property, and we can place our data into it according to the model.

Run the seeds

npx prisma db seed

And now, we should have our data in the database structured like this:

Database with new

Folders

If you are not sure how the folders should be structured I will add the screenshot, so you can check it.

Project structure

If you’re eager to continue the journey, feel free to dive into Part 3 and explore further enhancements for your Next.js app!

Thanks for reading my article!

If you enjoyed the read and want to be part of our growing community, hit the follow button, and let’s embark on a knowledge journey together.

Your feedback and comments are always welcome, so don’t hold back!

Stackademic

Thank you for reading until the end. Before you go:

  • Please consider clapping and following the writer! 👏
  • Follow us on Twitter(X), LinkedIn, and YouTube.
  • Visit Stackademic.com to find out more about how we are democratizing free programming education around the world.
Software Development
Nextjs
Prisma
Recommended from ReadMedium