(soft music) (upbeat music) - Welcome to "What's New in Prisma." We have a really, really
exciting release today, 3.01. This is the first major
bump that we've had. And the reason for this is that we have a lot of new features. Some of them contain
some breaking changes. But worry not, we have
a lot of upgrade guides. And we're also gonna work through all of these features
today in this live stream. So thank you for joining. Also, a quick reminder, that throughout this live stream you can drop your
questions in the live chat, on YouTube and we'll get to them. If it's something that is relating to something that we're doing now, obviously we'll get to it immediately. And otherwise if it's unrelated, we can get to it at the end. And today we have also, another special guest
from the Prisma team. He's been on the "What's New
in Prisma" live stream before. And we have today Matt Mueller. So I'm gonna bring Matt
Mueller to the stage. Matt, how's it going? - Hey, Daniel, doing well. How are you doing? - Pretty good, pretty good. I'm really pumped for this release. We've been in the
trenches for quite a while working on stabilizing
a lot of these features that are now gonna be generally available. Some of those include, the name constraints, referential actions. What's more? We have SQL Server and Azure SQL now in general availability. We have a new seeding API
that is a lot simpler to use. Node-API is generally available. OrderBy aggregate in groupBy queries, orderBy relation in queries, and select relation count. All of these things are
generally available. And some of you have tested
them while they were in preview. So, of course, your feedback has been immensely
helpful in shaping this. How has it been from your perspective sort of getting to this point, Matt? - It's been pretty amazing, actually. The team kind of rallied
behind this big release. I feel like we dropped so many things and we got so much done
over the last couple weeks and I guess probably months at this point. And, yeah, it's just been exciting to have so much to share
with the community. - Yeah. Well, I couldn't be more pumped. And someone even wrote, "I saw a really long changelog on GitHub." I think that was Khanh, yeah. And, yes, I think these are... 3.01 had the longest release notes. And so, yeah. It's been quite a lot. And, you know, instead
of talking about this, let's get into this. I'm gonna share my screen. Maybe we can start at the
top of the release notes. So let's see if we can get that going. And let's bring that on to the stage. All right. I'll make this a little bit bigger. So that all of you can see it. And, yeah. So as we've previously
previously mentioned, we've adopted Semantic
Versioning strictly, and this is why this is a major bump. If you're using tools like
Dependabot or Renovate, these are two automated tools
for managing dependencies. So the way that they
work, is that they create pull requests automatically for you in your repository on GitHub. I believe it also works with GitLab. They create pull requests with upgrades to your packages, and based on what you have in package.json. And you can configure them
also to automatically. I mean, if you have your tests
running in a pull request, you can configure it to
automatically merge it if it's just a patch, upgrade
and so on and so forth. So if you're not using these tools and you have a lot of repositories that you have to manage dependencies in, I highly recommend checking those out. It's called Renovate bot,
and Dependabot is built into GitHub, I believe. And this is the original blog post that we had mentioning the
details of Semantic Versioning. So check that out if you're not familiar. But I think many of you by now
are quite familiar with this, especially if you're working with Node.js where you have a lot of these dependencies in your package.json. So let's get into this release. So as I mentioned, here's a summary of all the different features. And we're gonna go one-by-one
and just unpack that. So referential actions. And referential actions is
now generally available. This is a feature that came up a lot in discussions about cascading deletes. So previously, if you were using Prisma, the way that Prisma would
work when you had say, the classic example of a blog, where you have a user
model and a post model, and you have one too many
relation between them. So each user can have many posts. The way that this was
created in the database, I believe by default, it
had cascading deletes. However, when you were using Prisma Client in order to delete a user, and that user had some related posts, it would prevent you from
doing that operation. And essentially, basically,
you didn't have the ability to do cascading deletes. And the way that referential
actions work is that they allow you to define
inside your Prisma schema, if you like, on the
relations, you can define how the behavior for these relation work. So for example, here
we have this LitterBox and this LitterBox has a relation to Cats. So there's a one to many between. One LitterBox can have many Cats. And as you can see here, we
have this onDelete, Restrict. So this is essentially the new syntax that is added into your Prisma schema. And because we have this
Restrict, essentially, you're not able to delete a LitterBox if you have Cats that
are associated with it. Of course, you can set that to Cascade. And then what will happen
is that deleting a LitterBox will automatically delete all of the Cats. And so this was initially introduced as a preview featuring
2.26.0 with a preview flag, and we've stabilized this. And so now this works if
you're using Postgres, if you're using MySQL, SQLite, Microsoft SQL Server and also Azure SQL. All of these databases,
you can now configure this. We also have an upgrade guide that will sort of work through the details if you're upgrading for the first time. And because essentially some
of the defaults will change, I highly recommend that you carefully read through this upgrade guide. And also when we get into the demo, we'll be able to take
a closer look at this and the different behaviors. Anything you wanna share Matt? - On referential actions, not necessarily. I guess maybe the one thing is, we're trying to be more
closer to the database. And so letting the
database handle this stuff. I think it's like a long time coming. Just letting the database do
the jobs that it's good at and we do the jobs that we're good at. So I think this is a nice improvement, even though it is a little bit of work if you been relying on
the previous behavior. - Yeah. Okay, so that was referential actions. And we're gonna look at named constraints and then we'll do the
first demo and go through named constraints and referential actions in action in the demo. So named constraints. This one is a bit of
a tricky one to tread, but if you bear with
me, I hope that you can sort of get this clearly. Basically named constraints or before I get into name constraints, I should say that one of
the core concepts in Prisma is this idea of the Prisma
schema being a single source of truth for both the application models, which you sort of access
through Prisma client, that is generated for you. And then the second thing
is for the migrations and for the database schema. So when you use the
Prisma Migrate command, or if you use the Prisma DB push command, what Prisma does is it
looks at your Prisma schema, it looks at your database,
and then based on that makes decisions about what needs to change in your database schema. And we had this challenge that essentially some people had
started projects by adopting Prisma into an existing
project that already had a database schema, and they
used introspection for this. So essentially they just
connected Prisma to the database. They use this Prisma DB pool command, which populated their Prisma
schema with all of the models based on the database schema. And then at that point they decided, okay, we want to create a new
development environment. In that development environment, they would create it using Prisma Migrate. So essentially they introspected
the production database or the existing database that they had. They had this Prisma schema
from which they created a migration in order
to run that and create, say a local development environment. And the problem there was
that the Prisma schema wasn't, when it was introspecting the database, it wasn't taking the names
of constraints into account. What happened as a result
of this is that many users noticed that when they
go to, when they create a new migration in
their local environment, say adding a new field, and
then they tried to run that against production, sometimes
they would run into errors because some of the
constraints weren't named exactly the same, and they
weren't named exactly the same because when they were introspected, they weren't represented
in the Prisma schema. And so what named constraints does is it essentially does two things. It makes the Prisma
schema a higher resolution representation of your database schema. And then the second thing is
it gives you control over how you choose to name constraints. And so we have an upgrade guide for this, and there's also an example,
but I think it will be better if we sort of get straight into the demo so that you can get this. And for the demo, what I have is, I'm just gonna open up Vs Code, is I have these, basically
this project here. It's a very simple Prisma
project where I have somewhat of an extension or a sort of
an addition to the classical example of the user and post model. And so here we have
essentially these three models, and the three models, I'll
make this a little bit smaller so that we can fit it all on screen. And by the way, we see
the questions coming in and we will get to them. I promise. So thank you, David, Joseph
and Ricardo for your comments. Okay, so let's go back to the example. So here we have these three
models, a user or that can have many posts and each one of these posts can have many comments. And these comments are
also related to an author, the person who wrote that comment. And in my package.json, if I open that up, you can see that I'm still
running version 2.30.3, which was the last version
before this new release that went out this week. And, I created the database schema using Prisma Migrate. So if I open up the
migrations, you can see here, there's this (indistinct)
migration where all of these tables are created for us. Oh, great. So that's all great. And now we're gonna work
through this upgrade process and we're gonna do that
by changing the version and upgrading Prisma
here to version 3.0.1. Oh. 0.1. I'll save that. Let me just look at the
read me to make sure that I'm following this demo. Yeah, so I showed you the Prisma scheme and the created migration. Now we're gonna do the
upgrade, and then we're gonna open up the Prisma schema. But first I need to
install the dependency. So let me just clear that. And so here, I'm gonna do npm install. By the way, if you wondered
what was helping me with the auto-completion
there, it's a tool called Fig, which I highly recommend you check out. It's a really nice way to get some rich autocompletion in your terminal. Okay. So we've now upgraded this to version 3.0, and then I'm gonna go back. I'll move this to the right,
and I'll close the sidebar. And let's look at the Prisma scheme. So, okay. So version 3.01 has been installed for us. Now we can go ahead and I'll clear this. And we can run the introspection command. What the introspection command
will now do is it'll populate Prisma schema with more information about our existing database. And this is an existing
database, that again, was just created with an
older version of Prisma. That was 2.30.2, I believe. So let's run the introspection command. That is npx Prisma db pull. Maybe it'll be better if
I pull this back down, and make this a little bit smaller. Okay. So I'm gonna run this DB
pull and we're gonna see how suddenly our Prisma
schema will be populated with all sorts of new fields. And sorry. New arguments, I meant. And there we have it. So we have a lot of these. I think I made a mistake here because we're not getting all of the maps. So I believe that I needed
to run a reset before. So I'm sorry about that. Before doing this. Welcome, Spiros. Nice having you here. Okay. All right. Now let's run introspect again and see if this works as I expect it to. There we go. Yeah, so I had made
changes prior to this demo, to the database schema. Hence, we didn't get all of that. But now that I've reset it
and it just executed the first migration that was created
with version 2.30.2 of Prisma. I introspected it. And now suddenly, we're
seeing more information inside our Prisma scheme. And a lot of what we're
seeing is these maps. So this map argument, essentially
when you use something like unique or you're
defining a foreign key or relation in simple
words, this is implemented in the database using what
is known as a constraint. And these constraint names,
the convention that Prisma used previously has now changed
to be a bit more consistent and to avoid some edged
cases where there were bugs. And so essentially now we
introspected this schema that was, and we have all of these. And now that you have these
in your Prisma schema, you basically have two options. You can either keep it there.
If you're happy with that. And now you have a high
resolution representation of your database schema,
and this will ensure that if you're recreating
this in multiple environments, that they will remain consistent. The second option, if you
don't like having all of this noise in your Prisma schema,
if it's not a problem for you to sort of like do these kinds of changes, then you can actually just go
ahead and remove all of these. And what will happen when we
remove a lot of these maps, Prisma will just default to
the new naming convention, to the default new naming convention. And it will create a migration
that we'll just rename the existing constraints
to the new default. And then that way you can
keep your prison schema clean without all of these maps. So I'm gonna remove this. I'm gonna remove this
map from these relations. And a quick note is that when you're using this map argument, the sort
of the way to remember is that map always impacts your database, essentially when you're
defining these constraints. And so the map is basically the underlying database constraint name. And so now I can remove this map and I can also remove these. And now if I'm gonna run Migrate, what we expect to see is
we're gonna get a migration that just alters, deletes
the old constraints and recreates them with
the new naming convention. So for this, I'm gonna use
the migrate dev command, which essentially looks
at the Prisma schema and then decides, looks at
the database schema and sees, oh, what has changed? And then based on that
creates this migration. And so I'm gonna name this
migration, renamed-constraints. And this has failed. And what it says is that the author ID does not exist on table comment. I think we may have not prayed to the demo gods prior to this. Okay. Please check the query number
seven in the migration file. Let's look at that. Drop foreign key. Okay. I think this might be
something specific to, something specific to MySQL, and we can get into that in a moment. If I put these maps back, let's see, and I delete this migration, and then I try to run dev again. Let's see if that works. Author ID. Yes. Okay. I think I may have needed
to run the, oh, there we go. Here's the name for the
new, rename-constraint. Constraint. And there we go. Okay, there we have it. So I can talk a little bit
about what happened wrong there. Basically, MySQL has
this interesting feature where you define a foreign key. And MySQL, essentially, when
you define a foreign key, you're defining a constraint. And what MySQL does on like Postgres, is that it goes ahead and
also defines a constraint. Sorry, did I say that correctly? So MySQL will, sorry, for a constraint, for a foreign key constraint,
it will also define an index. And this is why when we introspected, we got these @ @ index for these fields. And so you actually need to keep them. Now this may change in
an upcoming version. We're actually closely looking at this, but this is not a bug or anything. This is just a specific detail to MySQL, and we're gonna look at that. Okay, so what did we do? We removed a lot of the maps. These @ @ index are something
that is specific to MySQL. For now, it has to sort of stay there. But stay tuned. We may actually polish this so
you don't need to explicitly have this in your Prisma
schema because MySQL automatically creates that for you. And you're pretty much done at this point. What you would do is you
would run this against all of your environments. That's essentially what you would do. But again, you have this option of, if you don't want to go
through this trouble, you can just introspect it
and you'll get all of these explicit constraint names
in your Prisma schema, and you can sort of, if
you can live with that, that's also okay. And so that was the named constraints. And of course the upgrade
guide that we have also goes through all of the details. At this point, Matt, I want
to pause here and see if you have any comments about sort
of the process of what I did. - Not necessarily the process. Maybe a bit of color about
the name constraints issue. So, one thing that came
up quite a bit with people was if you came up with
an existing database and your constraint name had like a dot or a dash or something like that, and you tried to generate a Prisma client, because a dash isn't a valid TypeScript variable or keyword, so it would break. And so this will hopefully solve all of those issues as well. And so you don't really
need to worry about the constraint name affecting the name, like the API of the client
and having that break. So hopefully, this is a net positive. Although there are, I
guess, some hiccups still that we need to work through. But yeah, this should be good. - Great. And again, if you've created a new project or you're starting a new project now, you don't really need to think about this. You still write your Prisma schema, as you do always and by hand, and have the VS Code
extension, which helps you, especially if you're defining relations, and then you can just go
ahead and use Prisma Migrate. Okay. So we looked a bit at named constraints. The documentation goes
into this in great detail. And now I want to look
at referential actions. And so for this, I'm gonna open
up again, the Prisma schema. And in this Prisma schema, again, if we look at the relations,
we have a user with many posts and the posts with many comments, and those comments link back to the user. And you may notice that we have
this onDelete Cascade here. And what this means is when
you're essentially defining this @ relation attribute on a field, and that point, as you
can see here to post. What it says here is,
this onDelete behavior, you have a couple of options here. In Cascade, what that will mean is that if you delete a post,
all of the related comments for that post will also be deleted. And similarly, you could
also define this on the post. So for example, here, you
could say, onDelete, Cascade. And if I do this, I'm
gonna need to obviously run a migration for the
database schema to upgrade, and to reflect this change. What will happen is, what
we're gonna do is we're gonna create a user with some related posts and some related comments. And after we create that user, we're gonna just delete the
user and then we'll see how all of the related entities are deleted. And then we'll take a look
at the different behaviors that we have, like restrict,
NoAction, and so on. And so now that I've added
this onDelete Cascade here, I can go again into the
terminal and I can run prisma migrate dev. That will actually update. Again, this is just behavior
that you're defining in the Prisma schema, but it
is handled by the database. And so, change referential
or add Cascade to posts. And great. We can even take a quick look at what that migration looks like. And so this is basically
what has changed for us. Basically it's changed
to onDelete, Cascade and onUpdate, Cascade. And the onUpdate behaviors is essentially, if you want to have that cascading down. So if you change the user's
ID and that is the foreign key inside post model, then the
post record that is related to the user that has had his
ID change will also change his foreign key to point
to the new user ID. Okay, so I ran that migration. And let's look at the seeds script. And here essentially, this
is a really long create query to create a user, and
that user has a single post associated with it. And that post has two comments
by the author of the post that are linked to it. And that's all it does. And in order to make sure
that I'm running on a clean database and that I'm not sort
of like gonna mess this demo, I'm gonna just do it in migrate reset. And what that will do is
it'll essentially delete the database, recreate it,
and then run the seed script and it will recreate it, of course, using all of the migrations in
the Prisma Migrations folder. And yes, this is a local environment. One of the good things also
to note while this is running, is that we believe at Prisma
that a local development environments should be
cheap and quick to create. And this is why we have
a lot of this tooling, like the Migrate reset command, which essentially just
reruns, deletes the database, reruns migrations, and
then runs the seed script, so you know that you have a good baseline, especially if you want to run
integration tests or what not, or if you want to demo something, and you don't want to mess it up. Okay, so I ran this and
the seed script is there. I'm gonna also quickly open up Studio, that is Prisma Studio. And we have Prisma Studio. That's great. I'll open it here on the side. And speaking of tooling,
if you're a developer, since I mentioned Fig, I should
also give a shout out to... Why is that happening? To the creator of Rectangle. It's essentially a tool that
allows you to sort of like use keyboard shortcuts to move
screens around your Mac. You can sort of do a split
screen so I can move this to the left, and to the right. And I can open VS Code and have it exactly side-by-side with a Chrome. Sorry, my computer's
a bit overloaded here. But there we go there, we have it. So we have this user that
we created hanna@prisma.io, and she has one post. We can open that up and
we can see that here. And the author is indeed Hannah. And also we have two comments
that I believe she left on her own blog post as we created it. And then the user ID, the
author ID is indeed one, which points to Hannah. Okay. So what do we expect that
will happen if I delete this? Well, we expect because we
have a Cascade onDelete, that we just have to delete the user, and all of the related
entities will also be deleted. And too, I'm sure that there's
some viewers who are really experienced with databases
and this is quite trivial. So bear with me. I just think it's always good
to do these things slowly and explain them very carefully
for some of the beginners who might not be familiar with this. So thank you for your patience. And then here, I'm gonna
fetch the use user, and then I'm going to delete the user. I'm gonna log it and I'm
gonna delete the user, and then I'm just gonna try to find... You know what? We can skip this step and
just look at Prisma Studio. Great. And let's run this script. And for this, I'm just
gonna use npm run dev. And there we have it. So that was the user. And now if I reload
Prisma Studio, it's gone. And if I look at the posts, it's gone. If I look at the comments
and reloads, it's gone. So behaved as expected. That's all great. Now let's try to change that to restrict and see how it behaves then. Let's make this again. This is a short cut to
make it full screen, as I mentioned with Rectangle. And here again, I'm using
control space in VS Code, so I get this reach autocompletion. And what I can do is because
this is an optional relation, you can see that with this question mark, I can just set it to NoAction. So the posts will be kept, and the related comments will also remain because
the onDelete Cascade is only if you delete the post. So as long as the post stays there, the comments will stay there. But if we delete the post now, then also comments will be deleted for it. Okay. Let's create the migration, the same process as we did before. And we'll do that with the
prisma migrate dev command. And we'll name this, change actions. It's probably not the best name. But should work for our demo. And I'm just gonna for safety sake, also run the migrate reset command. We lost Matt, but hopefully he'll be back with us in a moment. - Sorry about that. - No worries.
- I had 1% on my computer, so I needed to plug in. (laughing) - Yeah. Good thing we're doing this in two. Okay. So now, it ran the seed
script again, which again, created that user with the
post and the two comments. And if I go back to the script,
let's take a look at that. And so, here again, I fetched the user and then I just delete the user. And what we should expect
to see is that the post will remain there, and also the comments. Hopefully that goes well,
because the comment I believe has a required relation to the user. So essentially here, we have this author, which is user and it's not optional. So it may actually fail. In fact, if it fails,
it's probably the correct thing to happen. So I ran the migration
and let's just go ahead and run this script and
see what happens, huh. So for that, just npm run dev. Yeah. And there we go. We got that error because
the foreign key constraint, again, it's a required constraint. So let's go back into the Prisma schema, and we can make that an optional one for cases where the user is deleted. And onDelete, actually, what
we want to do is we actually want to tell it explicitly, NoAction. Oh, sorry. NoAction. And this will exactly ensure the behavior that we mentioned before. You delete a user. The posts are kept, and
the comments are kept. And it's just that the comment
will lose its connection relation to the author
and so will the post. So again, we do the same spiel with, run the migration again, because again, we changed the schema. All right. And I should mention that
whenever I live stream, my CPU goes to %100, and this
is why this is a bit slow. I hope also the video is not too laggy. - It's working for me. - Okay, great. All right. So, we ran that. Again, for safety sake,
I like to run the reset just to know that I'm running
the right thing with the seed. I could have just called the seed script, but better safe than sorry. Okay, cool. Now it's running the seed command and then we can run this and see in... We can look here too, in Studio. Once the seed script finishes
running, there we go, we should be able to see it. There we go, and we have it. And then we have the posts, and we have also the two comments. So that's all good. Now we run the script with npm run dev. And hopefully it runs this time. Okay, that failed too. Let's take a look at the details. Okay. Foreign key constraint failed. Hmm, hmm, hmm, hmm. I have an idea. Wait, let me just open up. Matt, do you have an idea? Perhaps I have the schema
misconfigured here. - I'm not sure either, what's going on. Did you check that in the studio, that the schema shows optionals? Like, I'm wondering if it did get applied. - Oh, that's a good call. That's the wrong one. I'm sorry. Okay, we're back. So let's have a look at... It's just a bit slow here. So I'm just waiting for... Okay. Let's take a look at the migration. Oh, wait, sorry. That's the wrong project. And there we have it. Okay. Drop foreign key. So add onDelete. NoAction, onUpdate Cascade. Don't think this. Yeah.
- That seems okay. Unless you need to be explicit
in the sequel that drop the not null part of
it, 'cause it just says change the type to integer. I'm not sure if that means,
when you change it to integer, it would mean that it's now nullable. That's the only thing I
can think of that maybe... - I have an idea that we could try out. Let's delete all of the migrations, just to see if we can really get this. I think it's also a
tricky one because we have this sort of circular relation here, and I think it might be related to that. - Mmhmm, yeah. Maybe I'll take a question, actually while you're kind of looking at this. - Yeah, yeah, yeah. Feel free to go ahead with that. - Sure. - So Oscar asked, is there a way to handle not null constraints on new
fields with Prisma Migrate? So for example, if you
add a email later on, that's like a required
field, how would you add that to your Prisma schema,
if you've already got existing users basically? And I think the way to do that is, you can make it a required field, but then you need to set a default. So you would need to set at default, empty string or whatever
you want that to be, and then that should work. So then what happens is when
you run the migration on all of the previous rows that
didn't have that column, it would add the empty string. So that should work for you. - And let's make sure
that the seed script runs. - And Ricardo, do you mind sharing what kind of tool you mean? Like maybe a GraphQL tool? Or can you clarify what you mean by tool, or what you're looking for at least? - Okay. So now that we run this seed script, let's see if we have this here. And if we do, okay. Two comments in one post. Let's try to run the script again. (keyboard clicking) All right. That seemed to have also failed. And the foreign key constraint failed on field authorized ID. Okay. I guess it's hard for me to know. Okay, let's open up. I have an idea. 'Cause we don't have it set to restrict. So basically these are docs. And essentially there's NoAction. So in MySQL it behaves the
same as restrict, right. And then onRestrict, what it means. Okay. Oh, it prevents the deletion. Okay. Yeah, I know. It's behaving as correctly. I think it was just, I think it was set in null, that I wanted. Not NoAction. So this is again, it's a very
MySQL specific a example. And for that, what we're gonna do, is we're gonna change these to SetNull. And actually we achieved what we wanted. So restrict, which is the
same as NoAction in MySQL. Restrict will restrict
as we saw it restricted. SetNull should hopefully work
for us and essentially keep those related records, but still
delete the sort of original document that you're deleting. And so let's run again,
a migration to make sure that the database is now
using the correct foreign key constraint and has the right cascading configuration to SetNull. And this is essentially also
why we set these foreign keys to be optional with the question mark. Okay. And let's open up again, VS Code. Where was it? Yes. Oh yeah, sorry. Studio. Looks like it moved to the other screen. Okay. Let's take a look. Make sure that we still have this user. Yep. We still do, because the deletion
was correctly restricted. And maybe the demo gods are
with us today after all. Who knows. Okay. It looks like that worked. There was no error and that
was just a logging of that. So now let's take a look. And again, we expect to lose the user, but to still have the
two posts in the, sorry, the one post and the two comments. And okay, we lost the user, and we still have the post. And as we can see, probably
that there's no author ID. And then let's look at the comments. And if I reload them, we can see that the author ID is set to null. Okay. So that was referential actions. Again, this is why it's recommended to read carefully through the docs. My bad. Thank you for bearing me, and
thank you for your patience. And I think now we can sort of
move on to some of the other exciting features in 3.01. Let me just come back to the screen. See if there's any, okay, cool. Great, so we looked at that. Microsoft SQL Server and Azure SQL is now in general availability. Thank you for everyone
who's provided feedback. We were really excited
to sort of bring this, and there were a lot of
details that had to be sort of hammered out before we could
make this generally available. So I highly recommend that
you check out blog post, which you can find in the release notes. I can also show you a quick project that some of you may be familiar. I think I gave a bunch of talks
about GraphQL observability, and I mentioned it. And so this is a project,
essentially using Prisma with Fastify and Mercurius and Nexus, and the new Nexus Prisma plugin, in order to build a GraphQL API, and you get this sort
of full traceability. So you get these tracing
functionality that allows you to really debug requests. And so initially this was
written with Postgres, and this is what I meant
with the observability and the tracing. I can link to the talk
if anyone's interested. Just drop a line in the chat. But then because it was with Postgres and because one of the great
things about Prisma is really that it gives you that flexibility to change database if you need. Of course, this is not a common thing that you do with an existing application, but in reality, changing
a database does happen every once in a while. And because this is more
of an experimental project, I wanted to see what is it like to try this out with SQL Server? And so I went ahead and I
can open up the codebase. So this was our first example. I can close this. So that was named constraints
and referential actions. And I'll clean this up a bit here. But essentially here I have this same, the same data model as we saw before. And I'm gonna close that. So Prisma schema. And there we go. We have, again, the same idea, the user, the post and the comment. We also have this generator Nexus Prisma. I won't go into the details of that. But that really is what provides
in the GraphQL integration with Nexus in Prisma, called Nexus Prisma. There's a lot of clever
type generation that happens in the background to really
give you the same type safety that you get with Prisma,
but also on the GraphQL layer using this code first approach. And all I went ahead and did is I just changed this to SQL Server. I also deleted the old migrations
that were for Postgres. I did this, of course, in
a branch and I just ran it. And so after running the migrations, let me open up the right terminal window. Gonna make this a bit bigger so you can see what I'm writing here. So npm run dev. I have this running against... Oh, thank you. Yeah, I've done Fastify,
GraphQL Helix, Prisma and Nexus. That's awesome. I've actually been meaning
to check out GraphQL Helix. I'm just curious how that
integrates with Fastify. This is my reply to
Dregond, who mentioned that. Cool. So, really cool to hear. And okay, now we have
this GraphQL API running, and I can connect to it. What was the port? It was at 3000. And so, I'm using, Altair. It's another GraphQL IDE,
like GraphQL Playground. Really nice. You'll be able to see in a moment. And essentially here,
maybe we can even load up the actual schema of the GraphQL. Oh. Something is broken. What is broken? Let's try to run this, actually. Oh, I think I know why. And that's because I didn't connect 3000. So there's a course issue. Okay. That should solve it. Great. Okay. It's really cool to hear,
Ricardo, that you've used Helix and Envelop. Yeah, Envelop is really, really cool. Okay. So now we can, technically
we can just open up the GraphQL schema here. You can also check out the code. But the main thing I wanted
to show is just how easy it is to switch from Postgres to a SQL Server. And so I'll close that for now. And I can do wnip and creating a user, and then I can actually
create a draft of a post. I think it was because
I got the wrong thing. And, you know, I can go and toggle publish for this blog post. And so, now it's published
and I can also like it. And you'll be able to see, I
can call this multiple times because there's no limit on
how many times you can like. And you can also go ahead
and write a comment. And there we go. We can do it, and then we
can also look at the feed. And really, this was just... Okay, let's set this to true. And there we have it. And really, nothing in the
codebase changed besides of that. If you look at the GraphQL
schema, this is all using just Prisma and using this,
if you look here at some of the types, you'll be able
to see how they're projected from the Prisma schema. So since I'm already here, I
thought I should show this. And so, here we have it. We have this user type, and
then this is essentially coming from this Nexus Prisma plugin, which generates types that
you can use inside Nexus based on your Prisma schema. And that was also this generator
that we saw inside here, this Nexus Prisma generator. And so this is really nice
because as you can see here, I'm defining the field,
the type user.post. And user.post is
essentially the relations. And so what you get is you
get an automatically generated resolver that already solves
the N plus one problem for you. And so that was just a nice thing to show. If you're using Azure SQL, try it out. I've heard from a lot of SQL
Server and Azure SQL users, they've just tried out Prisma, introspected and existing database, and that were ready to go. There's also an interview
with Lewis who shares his experience doing this with
a 10 year old project. Okay, so that was a bit of a mouthful. And now I think we'll get to
the last part of the release. And that is all of these new
query types that allow you to do some more kind of like, more specific types of queries. And so I'll just drop the link to that. This is this Fastify project that I showed you with Nexus. So I dropped that. There's a branch there. I think it's called AzureSQL
if you're interested in checking out that. Okay, cool. So I mentioned also that
the Prisma DB seed command has been revamped. There's not really much
that you need to do if you're upgrading, All you need to do now is you have a, inside your package.json, you have here, this Prisma key. And inside, you have this seed. And essentially you can
provide any command you like, as long as it can run,
sort of in your terminal. You should be able to use, go. You should be able to use bash. Whatever you fancy, you can use that here. And if we look at the seed script, the one thing that does change, is that the seed script does, it's just calling a
script, a Node.js script. So of course, this is a TypeScript one. I'm using ts-node. But you need to actually
call the main function in it. So you actually need to make
the calls to the database, if you are upgrading
from an older version. In the older version, I believe that you just have to export. You have to use a default
export and then Prisma would sort of import that
and then run that for you. But now, because it's a bit
more flexible and simple, you just call that. So. Oh, wow. He got some interesting
story here from Dregond who's really active today. So awesome, that you're so active. He mentioned that he had a
client who was using an older version of .net application with SQL. I'm assuming probably SQL Server, and they needed to change
the front end really fast due to many issues, and
Prisma was a hero for that. So thank you for sharing that. I'd love to hear more
about their experience. So if you feel like
connecting them with me, you know my Twitter details. I'd love to hear more. Okay, cool. So we have the seed script. It just creates a bunch of users. We also have in the
Prisma schema, the city. And the reason that we have the city, is because I want to run all
sorts of interesting groupBy queries to showcase all of these new query methods that we have. So we looked at the seeding. And the first thing
that I want to look at, in terms of the new queries, we'll get maybe to Node-API after that, is the orderBy aggregate in groupBy. So this is a really cool way to sort of, if you're doing a groupBy
query and you want to orderBy essentially the count of
what you're grouping by. So for example, you have
many uses and they live in different cities and you
want to sort of get the count of how many people live in each city. You could have done that so far, but now with this new feature, what you can do is you can
also sort the results set based on that count that you
got from the groupBy query. And so what does that
look like in practice? OrderBy aggregate. So I have this script here. And basically all it does is it does this groupBy, and
it will group by the city. It will basically use the count
to count the unique cities, and then order it by
that in descending order. And let's run this. So npm run. And these, what I mentioned before, these are the recommendations
that you get with, what was it called? Fig. Yeah. Order by aggregate. That's the name of that
one that we want to run. Oh, that failed. Cannot find the module. Oh, I think it's because they just held it in the package json. So the demo gods are
intermittent today, I believe. But thank you for your patience. I see that it's still quite
a few of you viewing live. And let's just update this
to be the correct file name. I think it was just a T
that was missing there. And all right. We'll clear the screen and call the right. Okay, I believe it's
still called aggregate. But that should work. I'm just closing some
stuff in the terminal to speed up the computer. And there we go, okay. So we have basically two
users who are in Berlin, and we have one user who's in London. That was ordered by
aggregate in groupBy queries. Okay, the second thing we
have is order by relation. So this is really common. Say, you know, you want to query the post, but then you want to have all of the posts ordered by the author's name. Now you can do that. And it's really quite simple to do that. And so, order-by-relation. If we open that up, again,
we have very similar query where we order by, and
then we use essentially the relation object to tell it, aye, I want to order it by the name field in ascending order. So let's look at what that
looks like when I run it. And okay, it's almost freezing. So we want to run, npm run. Order-by-relation. And are we gonna get a result today? We are. Okay, cool. So we want to make sure of
course, that they're ordered. So we first have the
name Alice, and then Bob. If I changed this to... In fact, you can get this
order completion even for that. And let's run that again. We should see them in the
opposite order, essentially now. We're coming up on one hour. Wow. There we go. And now we have them, so. - It's a big release. - Yeah. Conny, Bob, and then Alice. And then if we change that again to... Did we have that many before? I dunno. I didn't order-by-relation. (keyboard clicking) All right. Let's see. Oh yeah. No, that's correct. Cool. So we had, really, these five and Alice, Bob and then Conny. Okay, so that was ordered-by-relation. And then finally we have this
select by relation count. And let's open up quickly the
release notes to look at that. So, select by relation count
allows you to count the number of related records by essentially passing the underscore count. You can use that inside selector inside, include depending on what
kind of query you're doing. And so, for example, here we have this, that will count the
number of posts per user. And this is a very common one, assuming that you are building
a blog and you have a feed and you want to get the number off posts that each user in this blog has, or if you want to get the number
of comments for each blog, when you're listing a story
for each article in a blog, because you want to sort
of show how much engagement you've had with that blog post. This is sort of a very
common use case for that. And let's look at the actual
query and we'll also run that. So here. Oop. Let me close that again. Yes. I think I can close this
and then open up again, the terminal, but move it
to the right-hand side. Okay. Okay. So yeah. Again, I'm finding many uses
and then getting the count for the related posts. That seems all trivial. We want to get a relation account. And let's see if my computer
still lives after this. I'll be thanking Tim Cook personally. Okay, great. That seems a bit strange because
we should have more users. Oh, I can remove this filter actually. It's not quite important. This is just fetching users who don't have any published posts. But we want to get all of the users. And we can actually add that. All right, let's run this again. And set select-relation-account. So I'm really curious to hear
back while this is running. I'm curious to hear, Ricardo,
what your experience was like with Helix and the Envelop. And here we have it. Okay. So we got now, the count
of posts for each user. But let's say I wanted to
sort of also order that by the count in descending order. Say I wanted to get all
of the most popular users or the most active users
in terms of the amount of articles they've written. And so I can combine that. And this is again, using
this order-by-relation, which we looked at just a moment ago. Matt, what were some of the, how did we sort of, oh yeah. Please show SQL queries if possible. Yeah, sure. I mean, we can, can do one with that. I can just pass here the log option. And I can pass a query, I believe. And then we can look at that. By the way, this is SQL Lite,
which if it's any consolation, that's running locally. That should be the fastest thing possible. But all right. So this is for you. I hope I'm pronouncing
your name correctly. Ilshat Khamitov. You asked me to show the SQL queries. And since you've stayed
around for so long, how can we not fulfill such a request? Okay, there you have it. It's not the most, not in
the most readable form, but I can maybe drop that
onto a JST, so that you can, if you're interested,
you can then Beautify it. And then again, we can
see also here that they're ordered in descending order. Okay, that was great. I think that's about it
in terms of the demos. I'm just gonna remove the screen, and let's change the overlay. Okay, so we're back here. There's 22 of you who
still sort of survived it. Thank you for bearing with us. We did skim over a Node-API
and I just wanted... Do you want to mention something shortly about Node-API, Matt? - Yeah. Sure. So for the longest time, we,
maybe for a bit of context, Prisma Client talks to the query engine, and the query engine does a
lot of the connection pooling and actually issuing the queries. And these are two separate processes. One is part of your application, and then one is a separate
REST binary process. You may have heard about that. For the longest time, the
communication has been either over a HTTP or Unix domain sockets. And so those are, they're okay. Like they get the job done,
but we were looking for ways of making it a bit faster. And so, something that
popped up was Node-API. And what no API does is you
can build the query engine, the REST binary in such a way
that it connects should be imported as a library into
your node application. And so then it lives in memory. So like, it's basically just
like any other node module. Like it's just passing things over. I think it's slightly slower
than if it was just completely node to node sort of, but it's very fast. And so, we're seeing a lot, a lot better performance out of... I think it's like cut in half, but then I'm seeing some people,
that it's like 5X faster. So, in this release. This has been an ongoing project
probably six months or so. And we had it in preview
for quite a long time. But this release, we finally said, okay, I think we're good. I think we should make this the default. And so, we've, with Prisma 3, now when you install the Prisma Client, the communication is through
Node-API and no longer through HTTP or Unix domain sockets. But if you run into any issues with that, you can always go back to the way it was. So we've just kind of switched, flipped the default
from opt in to opt-out. - Yeah. And you can, if you want to opt out, you can find that in the docs. I think one of the
coolest things about this, 'cause in the feedback
issue, I think we noticed, and also in the Slack,
a lot of people told us we've seen some really
wildly big performance improvements and some lower. And sort of my intuition
around that question of like, okay, why is it that
some get more benefits? I guess my intuition there
is that whenever there's more sort of memory usage in
sort of the passing through the operating system, essentially using a Unix domain socket, then
essentially you have also this, the serialization and the deserialization on sort of happening on both ends. And I guess that adds a lot of overhead that is now essentially eliminated. Is this the correct way
to think about this, Matt? - I think it's... So I'm not %100 sure exactly why there's fluctuations like that. I think that's definitely one way. I also think that the way Unix
domain sockets and TCP work, is there's a queuing system,
that internal queuing system, so if you're like running a bunch, it's gonna actually queue
in the operating system, and then like slowly give the messages to the query engine process. But this gets a bit out of my depth, exactly why and how it's faster. - Yeah. I mean, either way, this is
essentially using Node-API is now becoming more and more popular. I believe that SWR is using it. I believe Next.js is using it. What's the name of the new bundler? - SWC maybe? The REST one.
- SW, yes. I believe that's using it. And all of these tools, are
really trying to optimize for, these really modern tools that
are using REST really too, for the same reason that Prisma is really, we want to do all of the heavy lifting in a highly optimized environment, and REST is really ideal for that. And so we had a great question
from Dregond Rahl who asked, does it reduce the package
size to use an API, especially when dealing with labmdas. And I believe last time I
checked, I think it was like, not a major decrease, but it was like, I think two megabytes smaller, or I don't know what the percentage was, but I think it's around
the five to 10% decrease. So it's not huge, but
it is quite a saving. Is that also correct with what
you're familiar with, Matt? - Yeah, yeah. And so one thing to do about this, like this is kind of a
constant tug and pull. Like, as we add more features, the binary is gonna get bigger. There are things we can
do to make it smaller, but if you're running up against that, it's like 50 megabytes to, somewhere between 50
megabytes and 85 megabytes. If you're running into that,
you can always deploy your code to a S3 bucket and then
link that to Lambda, and then you don't have that limitation. So there is workarounds. So if you're constantly running into it, it's a little bit more infrastructure coordination.
- But actually, - I'm sorry, go ahead.
- I think it's. No, no, no. Sorry to cut you off. But actually, now that
I'm thinking about it, so if you've got my thoughts going, really if you're running Prisma in Lambda, you probably already have
issues that are not necessarily related to Prisma per se or any... I mean, you would have these problems with any ORM or any sort of tool. And that is the connection
management with your database. And really, I think
one of the great things that we have coming up
is the Prisma data proxy. That is part of our grand vision of the Prisma data platform. And so, in the very near future, what you will be able to do
is you will be able to use Prisma in environments like Lambda. We found actually having the
binary running on Lambda, and so what happens is, essentially
we run the Prisma engine binary for you in an isolated
environment, in the cloud. And that maintains a connection
pool to the database, essentially replacing PgBouncer. But the added benefit that you
get in such situation is that you also don't have to run the engine when you deploy it to Lambda. And so you get a much smaller
package and you get connection pooling out of the box,
and this is gonna be free. Free for, of course, within
some reasonable limits. But if you want to sign up for that, I will try to find the link
quickly to sign up for that. I believe I also tweeted
about it a couple of days ago. So really I'm super excited about. It's not just a developer
advocate at Prisma. I'm excited about this
because I really think this is something that
can push the ecosystem and there's gonna be some
really interesting ways to deploy essentially
applications, Node.js applications to the cloud and giving
you all of the benefits of serverless that you're
probably familiar with, with AWS Lambda, but with
a lot of the problems that are currently associated
with it, eliminated. And so really this is the vision
that we're working towards. And so, I saw you wrote
something in reply. Okay. He's writing, we use
layers with AWS London. It helps a lot with package sizes. Were there any other questions
that we didn't get a chance to get to before we wrap
up this live stream? I see. Okay, I see Spiros jumped
in, to chime in to some of the questions earlier. So, okay. We're about one hour and 15 minutes in. Thank you, if you've followed so far. If you find these live streams useful, please be sure to hit
the subscribe button. Or as many YouTubers like to say, smash that subscribe button. And Rahl, you were really. Dregond, you're really onto something. Could we use that with Cloudflare workers? All I can say is that we have
a surprise coming for you. And so with that, I'd like to thank you for joining us today. Thank you to everyone who's
tried out the preview features. And we have one more question. Do you think we can get to it? Oh, now everyone's waking
up with the questions. So Vivek, mine on enums. How to reuse enums between
Prisma and GraphQL. Ooh. I think that's a bit of a long one. Yeah, this is a tricky. It depends, really. I mean, you can just redefine them or, I think if you're using, I can't remember. 'Cause Nexus Prisma is
obviously in active development. It's in early preview now. Oh, you're using TypeGraphQL. Actually, I'm not a TypeGraphQL expert. So it's hard for me to
say what's the base, but I'm pretty sure that you
can project already enums from your Prisma schema
using Nexus Prisma, if you're using Nexus. Using TypeGraphQL, I
would highly recommend that you reach out to Michal, the creator. I believe I got his name correctly. All right, let's work through this. So we had one from Morritz. I want to start learning Prisma
along with Nest framework. Does the third major release
bring some breaking changes? Yes, it does. You can read all about
them in the release notes. If you're starting a new project, you shouldn't really worry a lot. If you have an existing project that you've already started with Nest.js, we have upgrade guides for
all of the breaking changes, and they're really nicely detailed out. And so, I highly recommend
you check that out. Nalaka, thank you so
much for the feedback. I'm glad that you enjoyed the demo. Thank you, Ricardo and the
Ilshat, and everyone who really participated in the chat. This makes it fun for us too, to know that someone's
on the other end of this, 'cause we just look at
the camera and blabber on. So with that, I won't continue. Matt, thank you so much for all the work that you put into making
this release happen. It's always fun having you on "What's New in Prisma." So I hope to have you here again. - Absolutely. Thanks a lot, Daniel. This is fun.
- All right. Goodbye, everyone.