Table Schema
The table schema is a defined... in a two places. The Prisma schema file, and then in each schema definition language file.
./api/db/schema.prisma
./api/src/graphql/user.sdl.js
User And Group Scheme
You can generate this same data from GraphQL Voyager.
Prisma Schema
The Prisma schema file (short: schema file, Prisma schema or schema) is the main configuration file for your Prisma setup. It is typically called schema.prisma and consists of the following parts. We're going to skip Generators as that's not generally unchanging.
- Data sources
- Data model
Data sources
Prisma supports only one data source. That value is set from your ./.env
file as DATABASE_URL
and is used to connect to your database.
Data model definition
The data model definition is where you define what models, fields, and relationships they have. Additionally, this is where at the database level you would define the type, default value, and other properties of the fields. Prisma has the most complete documentation on this here.
We'll highlight a few things that I think are important to understand.
Field Types
There's 10 types of fields in Prisma. They map to the actual types in your database depending on the database you use.
Attributes
Attributes modify the behavior of a field or block (e.g. models). There are two ways to add attributes to your data model:
Field attributes are prefixed with @
Block attributes are prefixed with @@
Some attributes take arguments. Arguments in attributes are always named, but in most cases the argument name can be omitted.
MongoDB is special in all of these cases, so I'm going to just omit them here.
Attribute | Database Type | Description | Notes |
---|---|---|---|
@id |
PRIMARY KEY |
Defines a single-field ID on the model. | Cannot by defined on a relation field. Cannot be optional. Functions can be used to auto-generate, autoincrement() , cuid() , and uuid() |
@@id |
PRIMARY KEY |
Defines a multi-field ID (composite ID) on the model. | See above |
@default |
DEFAULT |
Defines a default value for a field . | Not allowed on relation fields. Functions can be used to auto-generate, autoincrement() , dbgenerated() , cuid() , uuid() , now() |
@unique |
UNIQUE |
Defines a unique constraint on the field. | Not allowed on relation fields |
@@unique |
UNIQUE |
Defines a compound unique constraint for the specified fields. | See above |
@@index |
INDEX |
Defines an index in the database. | |
@relation |
FOREIGN KEY |
Defines meta information about the relation. | Takes 3 arguments, name , fields , references |
@map |
Maps a field name or enum value from the Prisma schema to a column. | Takes 1 argument, name |
|
@@map |
Maps the Prisma schema model name to a table. | Takes 1 argument, name |
|
@updatedAt |
Automatically stores the time when a record was last updated. | Compatible with DateTime fields | |
@ignore |
Ignores field when you introspect, excluded when generating client | ||
@ignore |
Ignores model when you introspect, excluded when generating client |
Commands to promote the migrations
The Prisma Schema file is where you would update the tables and columns on the database. When you modify your schema, you will need to run yarn rw prisma migrate dev
to promote those changes to the database.
You can interact directly with your database by running yarn rw prisma studio
to see the data as it exists in your database.
Schema Definition Language files
Once you have a Prisma Schema file, you still need to define your GraphQL Schema Definitions. Redwood has a generator for this yarn rw g sdl <table_name>
.
Schema Definition files have types, enums, queries and mutations. Those queries and mutations use functions defined in the services files.
Below is a SDL file query, and below that is the services file with it's appropriate function.
// api/src/graphql/user.sdl.js
export const schema = gql`
type User {
...
}
type Query {
users: [User!]! @requireAuth(roles: ["userRead", "admin"])
user(id: Int!): User @requireAuth(roles: ["userRead", "admin"])
}
...
`
// api/src/services/users.js
import { db } from 'src/lib/db'
import { logger } from 'src/lib/logger'
export const users = async () => {
let records = await db.user.findMany({})
return records
}
Further Reading
Redwood has some documentation but there's more on Prisma.