
Build a Fullstack Music App with Next.js Seeding Playlist Data Q&A
A second and third 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 an AI-Powered Fullstack Next.js App, v3 course.
Transcript from the "Seeding Playlist Data Q&A" Lesson
[00:00:00]
>> Good question, the question was, when does the run function actually get executed? Instead of just telling you when it gets executed, I'm gonna show you how you can figure that out. So if you look at the package.json, there's something you should have added at the bottom called prisma.
[00:00:17] And it has a seed property whose value points to something called ts-node. ts-node is just the node executable that understands TypeScript, so it can execute TypeScript files. Here's a flag that you can pass into the TypeScript compiler to tell it to use CommonJS modules. Because by default, TypeScript now uses ES6 modules.
[00:00:36] But Next.js uses TypeScript or CommonJS modules with Babel on top of it, so technically it's still CommonJS. And then the important part is that it's pointing to this file, prisma/seed.ts. So it's gonna execute this file. If we go to that file prisma/seed.ts, that's where the run function is.
[00:00:54] It's here. We wrote it there, and we executed it here. So the answer to your question is, this run function only gets executed when we run the seed command. That's it, it's a script that you run and then it stops. It's not an app that stays on. It has nothing to do with the front end.
[00:01:10] It has actually nothing to do with the back end either. It's just a script. Most apps have four different things going on. They have build time, so you have some process that's building your app. Think of Babel. Think of Parcel, think of Webpack. That's build time. You got runtime.
[00:01:26] That would be your app actually running in a browser or it running on a server. You have what I call dev time, that's you writing the code. So if you got TypeScript errors, you got ESLint errors. And then you have something called scripts. Scripts are just one-off things that don't actually, they're not meant to be running all the time.
[00:01:45] They might do some type of automation like copy this file here, or process this CSS, post CSS, or optimize these SVGs. It's kind of like the build system, but not exactly. It doesn't really build the app. It just does one little task and that's it. In this case, this one little task adds data to our database that we have on a Roku, that's it.
[00:02:07] So when our app actually starts up, there'll be data there for it to consume. Without that, we would have to go make some fake data in React. And which works, it's totally fine. But we won't get the benefit of being able to write code that accounts for error handling and loading states.
[00:02:23] Because we're not pulling the data from an API, we're just reading it from memory on the front end. Which as a UI engineer, as a product engineer, half of your job is writing, is loading. You gotta get used to that. So I want to make sure that we all have that.
[00:02:37] And the best way to do that is to put data in a database. On a real job, typically what might happen is someone on your team might give you a zip file that says here's a copy of staging, or a clean copy of production with all the stuff obfuscated, so you don't see the private stuff.
[00:02:53] Seed your database with this. That way your local database has a bunch of fake data in it, so you can test your applicants. You might have that in staging, you might have that in local. This is just our version of it. It's a script that generates that data, versus someone on our team giving us a zip file and inserting into our database.
[00:03:09] Because seed data is actually useful, so you can actually run your applicants. Imagine trying to build Facebook feed without any data in the feed. You wouldn't know what to make, nothing would show up. You would need some data there, so you can actually build the UI for it.
[00:03:25] It's the same thing, so we need that. We can't actually play any music until there's music in the database.
>> So each time you run that seed script, does it wipe out the data that's in the database?
>> Good question, the seed script doesn't do anything other than the code that we write.
[00:03:39] And based off the code that we wrote, because we're doing upsert which either updates or creates, no, it's not wiping everything out in the database. What's actually happening is, so for this upsert, so I already did this scenario. Let's say there's nothing in the database. We run the seed script the first time.
[00:03:57] All of these would go to create, because it would never find an artist with this name cuz it wasn't in the database yet. It's the first time we ran it. So these artists and these songs would get created. This user would get created, and these playlists would get created.
[00:04:11] That would be the first time. The second time you run it, assuming you didn't drop the database, it would come up here and it'll do the upsert again. It will see that there is an artist with this name, who I need to update with this, nothing. So it won't actually update it with anything.
[00:04:26] But it also won't create it, because it found it. So then it'll go to the next one, same thing here. And then you get down to this create here, which looks like it always creates a playlist, cuz we're not doing upsert. This would probably create another ten playlists, probably, cuz we're not doing an upsert.
[00:04:42] Or maybe prisma is smart enough to know that we're trying to seed it, and it'll write over it. But we're not doing the upsert here because we didn't know what the IDs were, so yeah. So to answer your question, no. But if you did wanna do that, what you could do is you could type in npx prisma migrate reset.
[00:05:02] And what that will do, well, basically is just drop the whole database. It'll literally drop the whole database, and then run the migrations against it. That's basically what it will do. But before you do that, you wanna make sure that you have all your latest migrations. I've been doing db push this whole time, so I need to run another migration before I do a reset.
[00:05:19] So what I'll do is I'll say npx prisma migrate dev. So this is me doing a git push of my database. I'm like, cool, I committed all my schema changes. I'm good to go. Let me push this up to database GitHub, basically, right? So I'm gonna do that.
[00:05:38] And of course, it's not --dev, it's just dev. There we go, so it's going to attempt to do that. Let's see what happens. It's basically saying here's all the changes that you did. You changed the Playlist table, you removed the userId. And you changed it to made it required, and you added another foreign key.
[00:06:00] You changed the Song table, you added a duration, you added a url. You sure that's what you wanna do? I'm like, yes, that's what I wanna do. And it's like, cool. I'm gonna go apply the previous migrations that you had before, that was successful. Name this new migration, I'm gonna call it song-stuff.
[00:06:22] Call it song-stuff. Looks like it was able to run the migration. It then generated a Prisma client. And then because we had that seed command in the package.json, it ran the seed script again to make sure you were good to go. So Prisma's pretty smart about keeping your database in sync.
[00:06:37] I really like that about them. It really makes it easy to keep everything in sync. I remember there was always one person on the team that has SSH into the database, and only they could run migrations and no one else. I was that person, it was terrible. I could never get time off.
[00:06:56] I'm chilling on the weekend, and someone needs to run a migration, cuz they work weekends. But only I can do it. I'm like, God, why did I sign up for this? Prisma makes that easy, so anyone can run migrations. Although, everyone should not be able to run migrations, only select a few.
[00:07:10] So yeah, good question.