Build a Fullstack Music App with Next.js Creating Schema & Migrations with Prisma
A second version of this course released using Next 13+, but this course is great if you want to see another example fullstack project. We now recommend you take the Build a Fullstack App with Next.js, v2 course.
Transcript from the "Creating Schema & Migrations with Prisma" Lesson
>> Sorry, I had to debug this Prisma foul, foul watching service for VS code. So if it's not working for you in VS code, it's not gonna be a deal breaker, you'll just have to type out the code yourself, but it's really nice to have this thing loaded.
[00:00:16] I think it really just depends on if you have some of the VS code setting set up to where it saves automatically. And I've tried to debug something that seems a lot of people are still having problems with that. VS code. Automatic saving stuff is a wormhole to deal with.
[00:00:31] But again, it's not needed. You'll just have to type out the code yourself. It's not a lot of code real only autocompletes one extra line. So it shouldn't be that big of a deal. Okay, so for right now we have an artist that is type artists. And we added this relationship, the fields that belongs to artist ID.
[00:00:51] The reason this isn't an array because you can have multi filled relations, and then it references the ID on the artist. And then we need to add an artist ID field that's a type integer. And then for the artists it's the same three fields that we have on everything else plus now we have a songs field that is a song array.
[00:01:10] So it's an array of songs. It's probably not the best place to put all the songs on an artist but depends on your View, it really depends on how you need to query things. Like I'm totally into denormalizing schemas and data if the UI needs it, like I'm totally for that.
[00:01:28] But again, I'm not some database expert. I'm more of a product person that's thinking like, how can I make one API call and get everything? I'm not thinking like, how can I save money on AWS? So it's not now but I'm doing. Okay, so we have an artist here artists also has a name, so we'll do that, make it a string.
[00:01:49] We'll make it unique, we'll make it, I think it's gonna help us create stuff a lot easier if it's unique. Artists also, we'll come back to that. The next thing we need is a model for a playlist. And same thing, all three of these things. And then a playlist also has a name, which is a type of string, and then a playlist also has songs.
[00:02:17] So what I can do is this will actually be like a many to many relationship where a song could belong to many playlists and playlists gonna have many songs. So what I could do is I can go to the song here, and I could say, playlists like so and make it a type play list.
[00:02:39] Like that, so it's part of many playlists. And then if your Autocomplete is working, what it would have done is it would have came down to the playlist model and added a song filled with a capital S I don't want that actually wants to be called Songs. I want it to be an array of songs on one to many to many.
[00:03:04] I'm gonna get rid of that. And I don't think I need this whole thing here. I just need that. So I have playlists, which is an array of playlist. And then I have songs which is an array of songs that was it. I don't need the whole relation thing just but things in there.
[00:03:24] So we got that. And then a user can have playlist. So we want the user to be able to have a playlist, and a playlist can belong to one user. So we have a one to many relationship here. So I can go back to the user and I can say you have playlists, plural.
[00:03:47] And it's gonna be typed Playlist. Somehow like that. So I'm gonna save that. And what that's gonna do is it's gonna generate a filter on a playlist. I'm just gonna type this out called user, Its type it's User with a capital U. And then we're gonna add a user ID filled.
[00:04:09] Whose type is integer. Oops, forgot the r. And we do need the relations decorator thing here because it's not a many to many. So for this we're gonna say at relation fields or points of the user ID. So we're referencing this field. And that user ID is referencing the ID of the user model up here.
[00:04:39] So the sweet thing about databases is that, you're probably never going to get it right the first time. So you got to run tons of migration until you finally get it right especially if you add a required field and you already have data in a database. What do you do with the data that was already there?
[00:04:55] Typically you got to run a migration to go through all that data and add the field or you set a default, so the defaults get applied at runtime. So to get around having to do that all the time Prisma has this thing called database push which is almost the same as a migration but it doesn't create a history.
[00:05:11] So it's basically meant for prototyping the schema without fully committing to, I'm done now. So what we can do when we're ready it's kinda doing a git commit but you didn't push it. I'm gonna commit these changes but I'm not gonna push them up yet because I'm not quite ready.
[00:05:30] When I push that means I'm ready. So what we can do is we can say npx prisma, you can do this at any time. You don't have to get to the point where I'm at npx prisma db push. Once you push up, you'll get some confirmation that Prisma is in sync with your database that you have deployed somewhere.
[00:05:49] And then it'll say generated a Prisma client. What that basically means is like, hey, we've notified the database about these schema changes. So now the schema are on your database, so they understand it, and we generated a client that client is gonna be used for us to query the database and it's gonna come with types generated based off our schema.
[00:06:08] So we'll have literally an SDK created just for our schema that knows about all of our fields and the types of those fields which is really cool and we can use. And because it's next to yes we can use that on the front end and the back end, so pretty dope.
[00:06:31] So I would say, for now, this seems like a good first draft. I know we still need albums, but we can come back to albums. If we need to make albums. We might not get to albums, which is fine because it's really not that an exciting feature to work on.
[00:06:47] But these are the main core things. This is gonna enable us to play some music and have playlists, which I think is probably the most important part. We did a lot of database stuff just now I know there's a lot coming at you, especially if you've never done any database work, a lot of these new terms, or this crazy stuff.
[00:07:04] But I promise you, it's never been easier to get started with a database. And today I'm ever trying to learn about databases ten years ago, I was like what? This sounds like rocket science. I don't understand what's going on. You had to understand index strategies and all this stuff.
[00:07:23] Now there's so many tools that just abstracted away from you where we know as an industry that this is the best way to do things. So we're just gonna do it this way. And it usually works for that 90% of the time until you get to scale you're serving hundreds of millions of users and you got to go custom but for most of the time, a lot of this stuff just kind of works for you out of the box.
[00:07:43] And again Prisma has really good documentation so, a lot of this stuff is actually on here, it kind of walks you through a lot of this stuff when I talked about those relations if you wanna know more about that. I'm totally down to talk more about that if anyone wants me to talk about that so like crazy to be talking many too many it literally goes in and talks about like how you do those many to many relationships and what they're for and why you have them and stuff like that.
[00:08:16] So it's it's pretty cool. Okay, now that we have that, I'm actually gonna go ahead and do our initial migration which will basically confirm the database changes that we made. Like here are the changes that we want. I think we're good, so this is like a push, there's like a git push, I'm gonna push these migrations up to the database and be like, I'm totally good.
[00:08:37] So now I can say npx prisma migrate dev. The reason I want to do dev is because I'm not ready to go to production yet, which will be like a different database, which we haven't made yet, cuz we haven't deployed. So I'm just gonna put dev I'm gonna run this migration.
[00:08:57] If it doesn't break, it'll say cool, we migrated your database, it's probably gonna ask for a name. Here we go, saying, hey, you're going to lose all the data. Here's all the changes that you made. So it's basically giving me like a diff of all my schemas, right?
[00:09:12] Literally just like a git push. I'm gonna say yes, I'm totally fine with that. Please do that is asking for a name for the migration. Typically you give your migrations name, just like you would a git commit to describe what you did on this database change. I'm just gonna call this init is the first time I actually did a migration.
[00:09:31] So we'll call this the init migration. Just like I would call my first commit init and there we go. You can see we made a new migration, it created a file for that migration thing, go check it out in a minute. And then it also generated the Prisma Client again to generate those types for TypeScript based off of our schema, which is gonna come in handy when we start creating the database.
[00:09:53] So now if we go look, you can see there's a migrations folder inside of PRISMA. It's got a migration file. Right here based off this date And you can see here all the changes I had to do it wrote the SQL for us which is really cool. I've had to write these by hand before and they're not fun I've literally broken in APA production so many times just getting this wrong.
[00:10:15] So yeah, this is not fun at all and the fact that they did it for us is just amazing, in my opinion. So really a big fan of that. One of the best database tools I've used in a while. Cool, any questions on the migrations there? Now as we go forward, we can make changes to the schema.
[00:10:37] And we can just keep running db.push, and it'll tell us if we need to run a migration or not. It'll detect a breaking change, like, You added a field that was required that requires a migration. You deleted a field that was required that requires a migration, or we might do something that doesn't require migration.
[00:10:53] Just like cool, you don't need a migration for this, you just added a field that wasn't required. You don't need a migration for that you're totally fine. So it'll detect the breaking change, which is extremely hard to do. Trust me, the company that I started, we literally had to do that on everyone's schema that they created for us and it was not easy to do.
[00:11:08] It took me like seven months to figure out how to do that. So really hard stuff to do [LAUGH]. So I'm really liking the fact that they have that for us.