In this chapter, we're going to set up our database. We're going to start by obtaining a connection URL using a Postgres database provided by Neon. We're then going to set up Prisma, our ORM. We're going to learn how to add and modify a Prisma schema, some basic migrations, as well as how to use a database studio, and also how to reset your database in case something goes wrong. And then we're going to go ahead and branch out, open up a pull request, and review and merge that pull request.
So let's go ahead and visit Neon database. You can use the link in the description or the link you can see on the screen to let them know you came from this video. Once you've created an account with Neon, go ahead and click create project. I'm going to go ahead and call my project Vibe and my database name will be Vibe as well. And then I'm going to click the connect button.
And I'm going to copy the snippet for my connection string. After that, I'm going to go inside of my project and I will create a new file, .environment. Inside of here, I'm going to create a database, underscore URL, and I'm going to paste my connection string. After that, let's go ahead and let's set up Prisma. You can use the link in the description or the link you can see on the screen to let them know you came from this video.
This helps me a lot in creating more content like this. So let's go ahead and learn how to use Prisma with Next.js. The first step is to set up the project. Since we already have that, we don't have to do that. Instead, we can go immediately to step 2, install and configure Prisma.
Since we are using other databases, specifically Neon, let's click here so we know what to install. So let's go ahead and start by installing Prisma and TSX as our dev dependencies. Once this was installed, I will just go ahead and go inside of my package.json so you can see the versions, right? Prisma is 6.10.1 and TSX is 4.20.3. So if you're using the latest versions this probably does not matter for you, but if you want to use the same versions as me you would go ahead and set up your installation like this for example if you want to.
Great, so after we've done this, our next step is to install Prisma Client, but this time not as a dev dependency, but as an actual dependency instead. After we've done this, let me show you the version. Prisma Client 6.10.1. So I think the most important thing about the Prisma versions is that Prisma client needs to match your Prisma dev dependency. At least at the time of me making this video, I'm pretty sure that is an important rule.
It might change in the future, so I'm not sure, but I think it was this way for a long time now. So now let's go ahead and let's actually run our app. So in here they have this snippet, but I'm not sure if this exact output will work with our directory because we have a source file here. So instead, what I'm going to do is I'm just going to run npx prisma init with nothing more. So npx prisma init.
Let's go ahead and run this. And after this was finished, I see this big log here. So your Prisma schema was created in prisma forward slash schema dot Prisma. Prisma would have added database URL but it already exists in your dot environment. You already have a gitignore file don't forget to add dot environment in here.
So pretty good warnings here. So yes, every time you run npx prisma in it, it creates an environment file or it modifies it and it adds a database URL. But this time it detected that we already have a database URL instead of our .environment, so it didn't do anything, right? Usually it would modify your .environment file and it would write a big message at the top saying modified or generated by Prisma. But the only thing you need in your environment is the database URL.
So even if yours looks different, maybe in the future they've changed this, all you need is a database URL for now. Great. So now let's go ahead and let's visit the other things added. Inside of Prisma folder we now have a schema.prisma and what's important here is that your provider is Postgres and that your URL is the database URL. So make sure you don't have any typos here.
But if you got this warning message, it means you have typed it correctly because it did not override it. And yes, about this second message, Don't forget to add the .environment in the gitignore file, that is very important. But as you can see, my .environment file is grayed out, which actually means it is inside of gitignore. You can find it right here. Great!
So now that we have that set up, let's go ahead and learn how to modify the schema. So I'm going to go ahead and I'm going to copy these exact changes that they are using in their Prisma. If you don't have access to that documentation page for whatever reason, don't worry, I'm just doing this as an example, our schema will be different anyway, or you can just pause the screen and type it out now. So basically we're adding a user model with an id of type integer and it will auto increment. Basically if I add one user it will be ID 1 and then I add another user it will be ID 2.
Then an email string which is required and unique and a name string which is optional. So basically Prisma is using decorators for stuff like defining a primary key or ID in this case, or adding the default value, or setting something to be unique. And if you want to make a field optional you simply add a question mark after its type. And if you want to make a relation like user and post, you start by defining, well obviously, your database structure, one to many, many to many, right? And then you simply add how you want it to be architectured.
So I want user to have many posts but I want post to have only one user. So you define the second model and you literally say it's an array of that model, right? And then inside of here in order to properly connect it using foreign keys what you have to do is you have to set the author id or the user id and then you have to create an actual relation using the foreign key. So you have to use user as the model and then you use a decorator relation. So it matches the author ID and it references the ID of the user model.
And this is the place where you would add things like onDelete, cascade, right? So in case the user gets deleted, we want the model post to get deleted as well. So you can remove this for now, just leave it exactly like this. This is like a pretty good minimal example to learn Prisma. And one thing I forgot to tell you, yes, you can install Prisma here to see the syntax.
I should have told you this before. My apologies, I just remembered. So make sure to install this, right? So you can see the pretty colors and everything. And once you've done this, make sure you save this file.
And let's go ahead and see how do we actually, you know, commit this, right? Because right now, our database here is completely empty. Nothing yet exists here. Nothing is pushed here. So let's go ahead and let's do npx prisma migrate dev.
I'm not going to do this flag because that's not how we're going to run our commands. So npx prisma migrate dev and now we're going to be asked to call this migration in a certain way. So I'm going to call this migration init. And just like that we applied the migration. And two things have happened now.
Actually, three things. The first thing is that it synchronized our database from Neon to the schema, right? So now our Neon database has the same schema there. The second thing it did is it created a migrations file instead of our project. And the third thing it did is it generated the Prisma client instead of source generated Prisma, right.
So let's try and check all of those things out. If you go inside of your Prisma, you can now see the migrations here. And instead of here, you can see the actual SQL file that happened. And the second thing you can see is, I'm not sure where is my generated, it's right here, source generated, there we go, you can see the Prisma is now available here. And the third thing that it did is it synchronized the NEON database.
So if you go inside of NEON and if you go inside of tables, I think you might be able to see, there we go, post and user, right? So you can see the exact fields here, title, content, published, author ID and user relation ID, email, name and posts relation. There we go. So we officially synchronized all of those things now. So let's go ahead and see the next steps that we have to do.
In here it suggests creating a seed script. Let's go ahead and do that, right? I'm going to copy this. You don't have to do this but I think it's a nice way to learn Prisma. Let's go inside of Prisma and let's create a seed.ts script like this and let's paste it inside.
Now in here I have to go inside of source I think. Let me just see how to access this. All right, found it. So it's source generated Prisma, right? We have to go inside of source generated Prisma.
It's not inside of app like they suggested here. Perhaps this depends on whether you use the source folder or not, or they've changed it. So they use the Prisma.userCreateInput. Now, if you're wondering where does this come from? How does it know user create input?
Why is this called user? Well, that's actually the magic of Prisma. Every time that you modify the Prisma schema and you run the proper command npx prisma migrate dev, which internally runs npx prisma generate, what basically happens is that it refreshes its internal intellisense typescript tool if I can call it like that and it creates a bunch of these useful types for you. So right now you also have things like Prisma. You can see all of these weird things.
If I think I can import user and I can import post, right? And if I were to add a new model, I would be able to import that as well. So that's the cool thing about Prisma. Perfect. So I have this user data here and let me just, if you are unable to copy this, let me just show you this first example and all the other ones are exactly like that.
And this is the bottom part, right? Or you can use the link that I will put in the screen for this seed script if you are unable to find it. Great. So now let's go ahead and let's add this to our package.json. So Prisma and Seed.
Let's go inside of package.json. So after scripts here, let's add Prisma, Seed, tsx Prisma forward slash Seed.ts, just ensure that yours is in the correct place. And once you've done that and saved the file, in here we have a warning. Before starting the development server, note that if you're using Next.js version 15.2.0 or 15.2.1, do not use TurboPack, right? So you can see that TurboPack sometimes has this small little issues, but since we are on a newer version, we should have no problems here, right?
And now let's go ahead and run npx prisma database seed here like that and that uses the tsx prisma seed and there we go the seed command has been executed So just make sure you have TSX installed in your dev dependencies and your seed command set at the correct place. And you should immediately be able to see this if you go inside of your neon database. And if you go inside of your users, you will see Alice and Bob inside of the users here. So we successfully populated our database. Perfect.
Another way of seeing this data is by using the Prisma Studio. So ntx-prisma-studio should open it up on 5.5.5. And there we go. You can see that inside of here. I have some posts and I have some users right here.
Alice and Bob. Perfect. Let's see what are the next steps here. So now we have to learn how to actually fetch our data. Right?
So let's go ahead and do that. I'm gonna go ahead inside of my project, inside of source, inside of lib, and I'm going to create a database.ts file. So they recommend creating Prisma, I like to call it database and I'm going to import Prisma client from generated Prisma. This is the same thing that they are doing. I'm just using an alias here And then you literally have to do the same thing here.
I'm gonna go ahead and try and explain how this works. So basically, why not just export new Prisma Client? The reason why is because of Next.js hot reload. Every time a hot reload happens, a new Prisma client gets initialized and that causes problems. And you would actually see a warning in your terminal about that.
So what they do is they store Prisma in a global because global as the window object is not affected by hot reload. I used the window object I'm not sure if this belongs to the window namespace Perhaps node namespace would be a better descriptor of it. And I also don't like to use the export default, so I will just use the export const here. And let me just put it here. Actually, I have to do it like this.
Okay. So now that we've done that, let's go ahead and let's try and query something. So I'm going to go inside of my source folder, inside of app.page.tsx, and I'm going to go ahead and import Prisma from lib database right here and I will get my users from await which means I have to turn this into an asynchronous component Prisma dot user and let's just use find many and then I'm gonna remove this entirely and do JSON stringify users null and two. And we can remove the button import. So this is a server component by default meaning that it is rendered on the server and it has access to the database.
Server component is not the same thing as server side rendering. Those are two different concepts. A server component is actually a React thing, not a Next.js thing. Next.js is simply the environment where server components can be demonstrated. So let's go ahead now and do npm run dev.
Let's visit localhost 3000. And in here, you should see a JSON of your users inside. And if you change this to post and change this to posts, you should be able to see posts here as well. So that is basically it right in here to go a bit more in depth. They're creating a whole, you know, unique include.
We're going to learn that through the project itself. So that's basically it for this, but there is one more thing I want to go over here so we added the schema we learned about basic migrations and we learned about database studio but we didn't learn about database reset So why do we even need to learn about database reset? Well, I just think it's very useful for development. So let me go ahead and actually modify this. So for development, right?
Not for production cases, right? You would pretty much never need to reset your database in production. But during development it's just super easy if you get stuck, right? Because this is the case now. So we now have some posts and we have some users, right?
So what happens if I go ahead now inside of my schema Prisma here. And for example, I remove the title from the post. It's no longer required. Or I remove the email. And if I go ahead and do that now, so npx Prisma migrate dev, I'm going to add this changes now.
It will probably ask me to reset database anyway, right? That's why this is a dev command, right? This should also not be used in production. You would usually do npx prisma migrate. You can learn more about that in the actual Prisma documentation here.
And there we go. So now we have a problem. You are about to drop the column title, which still contains non-null values, and you're about to drop the column emails. Are you sure you want to create and apply this migration? I'm going to select yes, and I'm going to call this test migration here.
And this time it worked, right? So this seems to be normal now. But the problem is, what if you do something more complicated? For example, let's try and let's drop the user here. And let's drop this.
Right, I'm trying to make a scenario where this actually stops working. Right. Let me try this. I'm going to do another migration. And I'm going to call this test again test two and okay it's still working never mind basically my point is that you need to learn how to nuke your database.
Let's say that you do some of your own experiments here and you get to a point where you're getting errors with your npx prisma migration. What I usually do if I get completely stuck and I'm in development, this is important, only for development mode, I would go inside of prisma here and I will remove all of my migrations, all of them. And then I would do npx Prisma migrate reset, like this. Are you sure you want to reset your database? All data will be lost.
And I will press yes, right? So, oh yes. I forgot that resetting it also runs the seed script. So let's remove the seed script because it doesn't make sense, right? We just use it to learn.
So we can remove that. We can go inside of our package.json and we can remove this. And we can also go inside of our source app page and we can remove this as well And then let's go ahead and just confirm that we can do npx prisma migrate reset again. So just confirm, and this should clear your entire database. Basically, this is quite useful in development mode when you are, for example, doing what we just did, right?
We just learned how to use Prisma, so we populated our database with some models we don't really need. We don't need the user with name optional and email required and posts, right? There's not going to be any posts in our project. So we just learned how to reset our database as well perfect so now it's time to create our first pull request once again the part of Git workflow of this tutorial is completely optional only for those who want to learn. So you can end the chapter here if you don't want to follow the Git workflow.
So what I'm going to do is I'm going to go ahead down here where it says main And I'm going to click create new branch. And I'm going to call this 02 and then I'm going to call it database. So I'm going to call my branches according to my chapter 02 database. And you can see that down here it says 0 to database. Then I'm going to go ahead and click the plus icon to add all of these changes and then I'm going to go ahead and add my 0 to database commit message.
And after that I'm going to publish my branch. And once I've done that I'm gonna go back to my github here and immediately you will see an option to create a pull request in my repository. If this did not appear for you, you can manually go inside of pull requests, new pull request, the base will be main or master depending on what you're using and you're going to select your new branch here in the compare and then create a pull request and then click create pull request right here. And once you've created your pull request you can go inside of file changes here and in here you can see every single thing that was modified. You can see that we added the Prisma client instead of our lib database, we slightly modified our page TSX and we added the schema Prisma.
We installed some new packages and we also added a source-generated Prisma to gitignore so that was not added. And after that we can go ahead and merge this pull request and click confirm merge. I'm not going to delete my branch simply so I have access to all of my branches here. You can see that I can now always go back to that state of the application. And then what you have to do inside of your project is the following.
Go down here and click on the 02 database branch and then you have to select your main branch. You might be wondering which one? This main or this main? Well basically the difference is one is a local branch and the other one is a remote branch. So the remote branch would be the one that is most, well, I would say that is the source of truth.
I could be wrong in doing this because you could have some changes on your main branches that you didn't push. But in our case, we're going to push everything from the main branch. So in your case, it doesn't matter if you click on this one, or if you click on this one, you will have the exact same result. What's important is that you do the following. You click on synchronize changes here and then OK.
Like this. And now you should no longer have any visible buttons here, right? And if you go inside of your graph, you should see this. An initial commit, then 01, and then something different for 02, right? Because we branched out.
And then we merged that back into our main, like that. And now, if you go ahead inside of your main here, you can see that six minutes ago we merged this, right? Perfect. So that's it for this chapter. You can now see that even though I'm in my main branch I still have my Prisma Schema meaning everything is fine.
Everything is good. Perfect. So let's go ahead and wrap this up. So I'm going to go ahead and, check this as done. Amazing job and see you in the next chapter.