title | langSwitcher | techMetaTitles | techMetaDescriptions | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Start from scratch with SQL Server |
|
|
|
Follow this tutorial to use Prisma with a Microsoft SQL Server database.
In order to successfully complete this guide, you need:
-
Node.js installed on your machine
-
A Microsoft SQL Server database
Make sure you have your database connection URL (including authentication credentials) available.
<SwitchTech technologies={['typescript', '*']}>
-
Create a project directory and navigate into it:
mkdir hello-prisma cd hello-prisma
-
Initialize a TypeScript project and add the Prisma CLI as a development dependency:
npm init -y npm install prisma typescript ts-node @types/node --save-dev
This creates a package.json
with an initial setup for your TypeScript app.
-
Next, create a
tsconfig.json
file and add the following configuration to it:{ "compilerOptions": { "sourceMap": true, "outDir": "dist", "strict": true, "lib": ["esnext"], "esModuleInterop": true } }
-
Invoke the Prisma CLI by prefixing it with
npx
- confirm that you can see the Prisma help screen:npx prisma
-
Set up your Prisma project by creating your Prisma schema file with the following command:
npx prisma init
This command created a new directory called
prisma
with the following contents:schema.prisma
: The Prisma schema with your database connection and the Prisma Client generator.env
: A dotenv file for defining environment variables (used for your database connection)
<SwitchTech technologies={['node', '*']}>
-
Create a project directory and navigate into it:
mkdir hello-prisma cd hello-prisma
-
Initialize a Node.js project and add the Prisma CLI as a development dependency:
npm init -y npm install prisma --save-dev
This creates a package.json
with an initial setup for a Node.js app.
-
Invoke the Prisma CLI by prefixing it with
npx
- confirm that you can see the Prisma help screen:npx prisma
-
Set up your Prisma project by creating your Prisma schema file with the following command:
npx prisma init
This command created a new directory called
prisma
with the following contents:schema.prisma
: The Prisma schema with your database connection and the Prisma Client generator.env
: A dotenv file for defining environment variables (used for your database connection)
To connect to your Microsoft SQL Server database:
-
Add the following line to the
client
block in your schema file to enable the Microsoft SQL Server Preview:generator client { provider = "prisma-client-js" | previewFeatures = ["microsoftSqlServer"] }
-
Set the
provider
andurl
fields of thedatasource
block in your Prisma schema as shown:datasource db { provider = "sqlserver" url = env("DATABASE_URL") }
-
Define the
DATABASE_URL
environment variable in theprisma/.env
file - this is the connection URL to your database.The following example connection URL uses SQL authentication, but there are other ways to format your connection URL:
DATABASE_URL="sqlserver://localhost:1433;database=mydb;user=sa;password=r@ndomP@$$w0rd;trustServerCertificate=true"
To get around TLS issues, add
encrypt=DANGER_PLAINTEXT
(not required in 2.15.0 and later if you are connecting to Microsoft SQL Server from MacOS specifically. -
Adjust the connection URL to match your setup - see Microsoft SQL Server connection URL for more information.
Make sure TCP/IP connections are enabled via SQL Server Configuration Manager to avoid
No connection could be made because the target machine actively refused it. (os error 10061)
-
Introspect your database to validate your connection URL - the CLI will throw a
P4001
error because your database is empty:
Deprecation warning
From Prisma 3.0.0 onwards, the prisma introspect
command will be deprecated and replaced with the prisma db pull
command.
```terminal
npx prisma introspect
```
```
Environment variables loaded from prisma\.env
Prisma Schema loaded from prisma\schema.prisma
Introspecting based on datasource defined in prisma\schema.prisma β¦
Error:
P4001 The introspected database was empty:
```
To create database tables, you can either:
- Use the
sqlcmd
command line tool (Docker) OR - Use SQL Server Managment Studio (Windows only)
Alternatively, try DataGrip, which supports multiple database engines.
To create tables using the sqlcmd
:
-
Paste the following SQL query into a file named
create.sql
, replacingUSE sample
with the name of your database - for example,USE myDatabase
:USE sample GO CREATE TABLE [User] ( id INT PRIMARY KEY IDENTITY(1,1) NOT NULL, name VARCHAR(255), email VARCHAR(255) UNIQUE NOT NULL ); CREATE TABLE [Post] ( id INT PRIMARY KEY IDENTITY(1,1) NOT NULL, title VARCHAR(255) NOT NULL, "createdAt" DATETIME NOT NULL DEFAULT GETDATE(), content TEXT, published BIT NOT NULL DEFAULT 0, "authorId" INTEGER NOT NULL, FOREIGN KEY ("authorId") REFERENCES [User] (id) ); CREATE TABLE [Profile] ( id INT PRIMARY KEY IDENTITY(1,1) NOT NULL, bio TEXT, "userId" INTEGER UNIQUE NOT NULL, FOREIGN KEY ("userId") REFERENCES [User](id) );
-
In your terminal, navigate to the folder with the
create.sql
file. -
Run the following command (change
sql1
to the name of your container) to copy thecreate.sql
from your local machine to your container's root folder:docker cp create.sql sql1:/
-
Run the following command to start an interactive bash shell, replacing
sql1
with the name of your Docker container:docker exec -it sql1 "bash"
-
Use the
sqlcmd
tool to run thecreate.sql
script, replacingmypassword
with your password:/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "mypassword" -i create.sql
-
To confirm that your tables were created, log in to
sqlcmd
:/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "mypassword"
-
Run the following command (you may need to copy-paste each line):
```terminal
USE my_database_name
:setvar SQLCMDMAXVARTYPEWIDTH 15
:setvar SQLCMDMAXFIXEDTYPEWIDTH 15
sp_tables
@table_type="'TABLE'"
GO
```
```
TABLE_QUALIFIER TABLE_OWNER TABLE_NAME TABLE_TYPE REMARKS
--------------- --------------- --------------- --------------- ---------------
mstest dbo Post TABLE NULL
mstest dbo Profile TABLE NULL
mstest dbo User TABLE NULL
```
</cmdResult>
</CodeWithResult>
To create tables SQL Server Management Studio:
-
Log in to SQL Server Management Studio.
-
Click the New Query button:
-
Change
USE sample
to use name of your database (for example,USE myDatabase
) and paste it into the query window:| USE sample GO CREATE TABLE [User] ( id INT PRIMARY KEY IDENTITY(1,1) NOT NULL, name VARCHAR(255), email VARCHAR(255) UNIQUE NOT NULL ); CREATE TABLE [Post] ( id INT PRIMARY KEY IDENTITY(1,1) NOT NULL, title VARCHAR(255) NOT NULL, "createdAt" DATETIME NOT NULL DEFAULT GETDATE(), content TEXT, published BIT NOT NULL DEFAULT 0, "authorId" INTEGER NOT NULL, FOREIGN KEY ("authorId") REFERENCES [User] (id) ); CREATE TABLE [Profile] ( id INT PRIMARY KEY IDENTITY(1,1) NOT NULL, bio TEXT, "userId" INTEGER UNIQUE NOT NULL, FOREIGN KEY ("userId") REFERENCES [User](id) );
-
Click the Execute button or press F5 on your keyboard to execute the query - you should see the following message:
Commands completed successfully. Completion time: 2020-10-25T10:55:16.0721284+01:00
-
Expand the database node in the Object Explorer to confirm that your tables were created.
Deprecation warning
From Prisma 3.0.0 onwards, the prisma introspect
command will be deprecated and replaced with the prisma db pull
command.
As a next step, you will introspect your database. The result of the introspection will be a data model inside your Prisma schema.
-
Run the following command to introspect your database:
npx prisma introspect
-
Open
prisma.schema
to see your data model:model Post { id Int @default(autoincrement()) @id createdAt DateTime @default(now()) title String content String? published Boolean @default(false) User User @relation(fields: [authorId], references: [id]) authorId Int } model Profile { id Int @default(autoincrement()) @id bio String? User User @relation(fields: [userId], references: [id]) userId Int @unique } model User { id Int @default(autoincrement()) @id email String @unique name String? Post Post[] Profile Profile? }
The introspected model contains auto-generated relation fields that do not adhere to Prisma's naming convention:
model User {
id Int @default(autoincrement()) @id
email String @unique
name String?
| Post Post[] // Should be `posts`
| Profile Profile? // Should be `profile`
}
Field names affect the shape of the Prisma Client - for example, a property named Post
that it is a list of posts. To adjust the data model:
-
Change the field names as shown:
model Post { id Int @default(autoincrement()) @id createdAt DateTime @default(now()) title String content String? published Boolean @default(false) author User @relation(fields: [authorId], references: [id]) authorId Int } model Profile { id Int @default(autoincrement()) @id bio String? user User @relation(fields: [userId], references: [id]) userId Int @unique } model User { id Int @default(autoincrement()) @id email String @unique name String? posts Post[] profile Profile? }
-
Introspect again to confirm that Prisma does not overwrite your manual changes.
Prisma Client is an auto-generated, type-safe query builder based on your data model. To get started with Prisma Client:
-
Install the
@prisma/client
package:npm install @prisma/client
-
Run the following command to generate your Prisma Client:
npx prisma generate
prisma generate
reads your Prisma schema and generates your Prisma Client library into a folder named .prisma/client
, which is referenced by node_modules/@prisma/client
.
<SwitchTech technologies={['typescript', '*']}>
-
Create a file named
index.ts
and add the following sample code:import { PrismaClient } from '@prisma/client' const prisma = new PrismaClient() async function main() { // Create a user and two posts const createUser = await prisma.user.create({ data: { name: 'Alice', email: 'alice@prisma.io', posts: { create: [ { title: 'My first day at Prisma' }, { title: 'How to create an Microsoft SQL Server database', content: 'A tutorial in progress!', }, ], }, }, }) // Return all posts const getPosts = await prisma.post.findMany({}) console.log(getPosts) } main() .catch((e) => { throw e }) .finally(async () => { await prisma.$disconnect() })
-
Run the code with the following command:
npx ts-node index.ts
You should see the following output:
[ { id: 1, title: 'My first day at Prisma', createdAt: 2020-10-26T08:24:10.966Z, content: null, published: false, authorId: 1 { id: 2, title: 'How to create an Microsoft SQL Server database', createdAt: 2020-10-26T08:24:10.966Z, content: 'A tutorial in progress!', published: false, authorId: 1 } ]
-
Change
email: "alice@prisma.io"
to another email address and run the code again to create another user and list of posts.
<SwitchTech technologies={['node', '*']}>
-
Create a file named
index.js
and add the following sample code:const { PrismaClient } = require('@prisma/client') const prisma = new PrismaClient() async function main() { // Create a user and two posts const createUser = await prisma.user.create({ data: { name: 'Alice', email: 'alice@prisma.io', posts: { create: [ { title: 'My first day at Prisma' }, { title: 'How to create an Microsoft SQL Server database', content: 'A tutorial in progress!', }, ], }, }, }) // Return all posts const getPosts = await prisma.post.findMany({}) console.log(getPosts) } main() .catch((e) => { throw e }) .finally(async () => { await prisma.$disconnect() })
-
Run the code with the following command:
node index.js
You should see the following output:
[ { id: 1, title: 'My first day at Prisma', createdAt: 2020-10-26T08:24:10.966Z, content: null, published: false, authorId: 1 { id: 2, title: 'How to create an Microsoft SQL Server database', createdAt: 2020-10-26T08:24:10.966Z, content: 'A tutorial in progress!', published: false, authorId: 1 } ]
-
Change
email: "alice@prisma.io"
to another email address and run the code again to create another user and list of posts.