We will first set up postrgreSQL, if you already have your database, skip this section.
If you like the interactive way of installing, you can dowload the installer here. However, I found that downloading using this method makes it really hard to make customization as all the config files are initally locked and you will have to manually change access permision for all.
In this article, we will install using homebrew. You can find out more about other installation methods here.
Run the following command from your terminal.
brew install postgresql@16
This will install PostgreSQL 16, expose it to Port:5432, as well as creating a default database with name postgres at the following location /opt/homebrew/var/postgresql@16.
To create a new database, you can use the follwoing command.
initdb --locale=C -E UTF-8 path_to_your_directory
This will create a new database at path_to_your_directory with locale setting to C and encoding setting to UTF-8.
You can find out more about the argument you can pass into initdbhere.
We will be using the default database created by brew initially in this artical.
Here are couple really useful commands .
To start postgresql@16 now or restart at login: brew services start postgresql@16
To stop the service: brew services stop postgresql@16
To get the list of service you have: brew services list
To connect to the server and enter SQL command: psql postgres
DataBase Visualization
I have also installed DBeaver for database visualisation.
Let’s first create a new connection by click on the icon below.
This will take us to Select your database. Choose PostgreSQL and let’s configure our connection setting.
The basic schema for your database URL will be look like the following.
jdbc:postgresql://{Host}:{Port}/{Database}
And in my case, this will be:
jdbc:postgresql://localhost:5432/postgres
You can find out the Username by running brew services list and it is the User.
Name Status User File postgresql@16 started itsuki ~/Library/LaunchAgents/homebrew.mxcl.postgresql@16.plist
And for the Password, you can leave it empty.
Choose Finish.
Double click on the database name on the left side panel and you will be able to connect to it. You should see the green check back under the elephant icon.
Having our PostgreSQL database set up, we can now moving onto creating and configuring our Next.js project and Prisma.
Set Up Next Js with Prisma
Create new project
First of all create a new next js project like following.
Go to your project directory and install the following libraries.
npm install prisma @prisma/client
After the installation, we can then initialize Prisma with
npx prisma init
This command will
create a new directory called prisma with a new file called schema.prisma that contains the Prisma schema, database connction variables and schema models. We will take a more detail look at it later.
creates the .env file in the root directory to which we will be adding the database connection URL.
In addtion, you can also add Arguments to it. We will be adding schema to ours. If schema is not set, it will automatically set to the default, ie: public, but let’s just add it anyway. The URL scheme will become the following.
I actually don’t have to change anything in my schema.prisma . The provider is default to postgresql, and url being set to the environment variable. If yours looks different, change it to the following.
datasource db { provider = "postgresql" url = env("DATABASE_URL") }
Defining the Database Schema
This section is only for those of you who have an empty database or wish to add new tables to your database.
If that’s not you go, ie: you already have your database created and not going to add any new table, you can simply run the following command to turn your database schema into a Prisma schema and head to the next session.
npx prisma db pull
Suppose we want a (new) table storing User data in our database. Here is the model we will be adding to our schema.prisma.
model User { id Int @id name String }
The User model two columns.
an id column of type Int which is the primary key
a name column of type String.
By the way if you don’t have any schema from the beginning, this will create a new schema with User table.
After defining the model, we can deploy it to our database using
npx prisma db push
You can check your DBeaver and should observe something similar to the following with your User Table with defined columns showing up.
Let’s add couple rows to the column so that we can query on it later.
Double click on your User Table and select Data Tab at top. Right click anywhere on the Grid and choose Add row. I have add itsuki and itsuki2 as my user for demo purpose.
Use Prisma in Next.js
Generate Client
First of all, let’s generate a Prisma Client that is tailored to our models by running the following command.
npx prisma generate
This command is actually also invoked when we installed @prisma/client, and you might and should see the following already showing up at the top of your schema.prisma file. But let’s run it again since we have modified Prisma schema.
It is actually a little bit tricky when creating client instance within NextJs.
If you simply do const prisma = new PrismaClient() as what the tutorial for Node.js suggest, you might get the following error or stay in the loading state forever (that’s me, I am not getting the actual error on my console though).
warn(prisma-client) There are already 10 instances of Prisma Client actively running.
The problem is that in development environment, the command next run dev clears Node.js cache on run. This in turn initializes a new PrismaClient instance each time due to hot reloading that creates a connection to the database. This can quickly exhaust the database connections as each PrismaClient instance holds its own connection pool and you will get the following error. You can get more details about the issues here.
Here is the solution.
Let’s create a new lib folder under src and add prisma.ts to it.
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
The idea here is to instantiate a single instance PrismaClient and save it on the globalThis object.
We will check globalThis to see if anything is stored on it. If nothing is on the object, we will create a new PrismaClient; otherwise, we will just reuse the one stored.
We can now import the client when we need it and start querying database.
Query Database
There are couple ways to use Prisma to query database within Next Js.
getStaticProps
getServerSideProps
API Routes
Let’s start with a simple example where we will list all the users we have in the database. To do that we will be using the findMany() api in the format of prisma.$modelName.findMany() .
There are many many more APIs provided by Prisma that really makes life working with relational database such as PostgreSQL so much easier so check out what you can do here.