Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions content/02-understand-prisma/02-features.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,10 @@ Lock option (MySQL):
| `autoincrement()` | Yes (via the `SERIAL` type) | Yes (via the `AUTO_INCREMENT` keyword) | Yes (via the `AUTOINCREMENT` keyword) |
| `now()` | Yes | Yes |

## Type mappings between Prisma and database

TBD for different scenarios:

- Introspection
- Migrations
- Raw SQL

## Queries (Prisma Client API)

- eager and lazy loading
- CRUD
- field selection
- raw database access
- advanced filter api on relations
Expand Down
6 changes: 3 additions & 3 deletions content/02-understand-prisma/05-data-modeling.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ It has the following columns:

- `user_id`: An integer that increments with every new record in the `users` table. It also represents the [primary key](https://en.wikipedia.org/wiki/Primary_key) for each record.
- `name`: A string with at most 255 characters.
- `email`: A string with at most 255 characters. Additionaly, the added constraints express that no two records can have duplicate values for the `email` column, and that _every_ record needs to have a value for it.
- `email`: A string with at most 255 characters. Additionally, the added constraints express that no two records can have duplicate values for the `email` column, and that _every_ record needs to have a value for it.
- `isAdmin`: A boolean that indicates whether the user has admin rights.

### Data modeling on the application level

Additionally to creating the tables that represent the entities from your application domain, you also need to create application models in your programming language. In object-oriented languages, this is often done by creating _classes_ to represent your models. Depending on the programming language, this might also be done with _interfaces_ or _structs_.
In addition to creating the tables that represent the entities from your application domain, you also need to create application models in your programming language. In object-oriented languages, this is often done by creating _classes_ to represent your models. Depending on the programming language, this might also be done with _interfaces_ or _structs_.

There often is a strong correlation between the tables in your database and the models you define in your code. For example, to represent records from the aforementioned `users` table in your application, you might define a JavaScript (ES6) class looking similar to this:

Expand Down Expand Up @@ -185,7 +185,7 @@ export declare type User = {
};
```

Addtionally to the generated types, Prisma Client also provides a data access API that you can use once you've installed the `@prisma/client` package:
In addition to the generated types, Prisma Client also provides a data access API that you can use once you've installed the `@prisma/client` package:

```js
import { PrismaClient } from '@prisma/client'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: 'Connectors'
title: 'Data sources'
metaTitle: ''
metaDescription: ''
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,17 @@ Enums are considered [scalar](#scalar-types) types in the Prisma data model. The

Enums are defined via the `enum` block.


## Naming enums

Enum names must start with a letter. They are are typically spelled in [PascalCase](http://wiki.c2.com/?PascalCase) and use the singular form (e.g. `Role` instead of `role`, `roles` or `Roles`).

Technically, an enum can be named anything that adheres to this regular expression:

```
[A-Za-z][A-Za-z0-9_]*
```

### Examples

**Specify an `enum` with two possible values**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ On a technical level, a model maps to the underlying structures of the data sour

## Naming models

Models are typically spelled in [PascalCase](http://wiki.c2.com/?PascalCase) and use the singular form (e.g. `User` instead of `user`, `users` or `Users`).
Model names must start with a letter. They are are typically spelled in [PascalCase](http://wiki.c2.com/?PascalCase) and use the singular form (e.g. `User` instead of `user`, `users` or `Users`).

Technically, a model can be named anything that adheres to this regular expression:

```
[A-Za-z_][A-Za-z0-9_]*
[A-Za-z][A-Za-z0-9_]*
```

Note that naming conventions in databases wildly differ. A common approach for naming tables in databases is to use plural form and [snake_case](https://en.wikipedia.org/wiki/Snake_case) notation, e.g. `users`. When introspecting a database where a table is called `users`, you'll end up with a model looking similar to this:
Expand Down Expand Up @@ -99,12 +99,12 @@ Here's an overview of these for the fields from the `User` model [above](#exampl

### Naming fields

Field names are typically spelled in [camelCase](http://wiki.c2.com/?CamelCase).
Field names _must_ start with a letter and are typically spelled in [camelCase](http://wiki.c2.com/?CamelCase).

Technically, a field can be named anything that adheres to this regular expression:

```
[A-Za-z_][A-Za-z0-9_]*
[A-Za-z][A-Za-z0-9_]*
```

> **Note**: There's currently a [bug](https://github.com/prisma/prisma2/issues/259) that doesn't allow for field names prepended with an underscore. The current regular expression for valid field names therefore is: `[A-Za-z][A-Za-z0-9_]*`
Expand Down Expand Up @@ -161,9 +161,10 @@ When annotated with the `[]` type modifier, a field becomes a list. This means i

#### Optional vs required


When **not** annotating a field with the `?` type modifier, the field will be _required_ on every record of the model. This has effects on two levels:

- **Database**: Required fields are represented via `NOT NULL` constraintß in the underlying database.
- **Database**: Required fields are represented via `NOT NULL` constraints in the underlying database.
- **Prisma Client**: Prisma Client's generated [TypeScript types](#type-definitions) that represent the models in your application code will also define these fields as required to ensure they always carry values at runtime.

### Model attributes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,9 @@ For **1-1 and 1-n relations**, pne side of the relation represents a foreign key

![](https://imgur.com/kOO4eh2.png)

For **implicit m-n-relations**, both relation fields are virtual since neither of them directly maps to a foreign key:
For **implicit m-n-relations**, both relation fields are virtual since neither of them _directly_ maps to a foreign key:

![](https://imgur.com/01pxhWM.png)
![](https://imgur.com/DxuOs88.png)

Prisma always requires both sides of a relation to be present, this means that one virtual relation field always needs to be added per relation. When [formatting the Prisma schema](), the formatter automatically inserts any missing virtual relation fields for you to save some typing work.

Expand Down Expand Up @@ -432,12 +432,12 @@ To summarize, these are the rules for determining which side of a 1-1-relation h

Here's the summary in the form of a table assuming the two relation fields of the models from before `Profile.user` and `User.profile`:

| `Prrofile.user` | `User.profile` | Foreign key on | `@relation` attribute |
| :-------------- | :------------- | ----------------------------------------------------------- | ------------------------------------------------- |
| Required | Optional | `Profile` (because the relation field on `User` is virtual) | Can't be used to determine the foreign key |
| Optional | Required | `User` (because the relation field on `Profile` is virtual) | Can't be used to determine the foreign key |
| Optional | Optional | `Profile` (because it's first in the alphabet) | Can be used to manually determine the foreign key |
| Required | Required | `Profile` (because it's first in the alphabet) | Can be used to manually determine the foreign key |
| `Profile.user` | `User.profile` | Foreign key on | `@relation` attribute |
| :------------------------ | :------------------------ | ------------------------------------------------------------ | ------------------------------------------------- |
| Required | Optional | `Profile` (because the relation field on `User` is virtual) | Can't be used to determine the foreign key |
| Optional | Required | `User` (because the relation field on `Profile` is virtual) | Can't be used to determine the foreign key |
| Optional | Optional | `Profile` (because it's first in the alphabet) | Can be used to manually determine the foreign key |
| Required | Required | `Profile` (because it's first in the alphabet) | Can be used to manually determine the foreign key |

## One-to-many

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Generating Prisma Client requires three steps:

Here is a graphical illustration of the typicaly workflow for the Prisma Client generation:

![](https://imgur.com/fZ5rtVg.png)
![](https://i.imgur.com/aRJmVFY.png)

Note also that `prisma generate` is _automatically_ invoked when you're installing the `@prisma/client` npm module. So, when you're initially setting up Prisma Client, you can typically save the third step from the list above.

Expand Down Expand Up @@ -63,9 +63,9 @@ The `@prisma/client` node module is different. It is a "facade package" (basical

While you do need to install it _once_ with `npm install @prisma/client`, it is likely that the code inside the `node_modules/@prisma/client` directory changes more often as you're evolving your application. This is because the directory contains code that is _generated_ based on your Prisma schema. When your Prisma schema changes (e.g. because you perform a [schema migration]()), you need to re-execute `prisma generate` which takes care of updating the code in `node_modules/@prisma/client` so that it reflects the schema changes.

Because the `node_modules/@prisma/client` directory contains some code that is _specific_ to _your_ project, it is sometimes called a "smart node module".
Because the `node_modules/@prisma/client` directory contains some code that is _specific_ to _your_ project, it is sometimes called a "smart node module":

![](https://imgur.com/5HuBN2G.png)
![](https://i.imgur.com/83djlkl.png)

### Why is the "facade package" needed if Prisma Client is generated?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ model User {
}
```

**Naming of relation fields**
**Naming of foreign key relation fields**

Foreign keys are represented as _relation fields_ in the Prisma schema. Here's how all the relations from the SQL schema are represented:
Foreign keys are represented as [relation fields]() in the Prisma schema. Here's how all the relations from the SQL schema are represented:

```prisma
model categories {
Expand Down Expand Up @@ -240,4 +240,57 @@ const userByProfile = await prisma.profile
.user();
```

> **Warning**: `@map` and `@@map` attributes are removed when you run `prisma introspect` again. You might want to back up your Prisma schema with these attributes in order to not having to annotate everything from scratch again after a re-introspection.
> **Warning**: `@map` and `@@map` attributes are removed when you run `prisma introspect` again. You therefore might want to back up your Prisma schema with these attributes in order to not having to annotate everything from scratch again after a re-introspection.

## Renaming virtual relation fields

[Virtual relation fields]() only exist in the Prisma schema, but are not actually manifested in the underlying database. You can therefore name these fields whatever you want.

Consider the following example of an ambiguous relation in a SQL database:

```sql
CREATE TABLE "User" (
id SERIAL PRIMARY KEY
);
CREATE TABLE "Post" (
id SERIAL PRIMARY KEY,
"author" integer NOT NULL,
"favoritedBy" INTEGER,
FOREIGN KEY ("author") REFERENCES "User"(id),
FOREIGN KEY ("favoritedBy") REFERENCES "User"(id)
);
```

Prism's introspection will result in the following Prisma schema:

```prisma
model Post {
id Int @default(autoincrement()) @id
author User @relation("Post_authorToUser", references: [id])
favoritedBy User? @relation("Post_favoritedByToUser", references: [id])
}

model User {
id Int @default(autoincrement()) @id
Post_Post_authorToUser Post[] @relation("Post_authorToUser")
Post_Post_favoritedByToUser Post[] @relation("Post_favoritedByToUser")
}
```

Since the names of the virtual relation fields `Post_Post_authorToUser` and `Post_Post_favoritedByToUser` are based on the generated relation names, they don't look very friendly in the Prisma Client API. In that case, you can rename the relation fields to anything you like, e.g.:

```prisma
model Post {
id Int @default(autoincrement()) @id
author User @relation("Post_authorToUser", references: [id])
favoritedBy User? @relation("Post_favoritedByToUser", references: [id])
}

model User {
id Int @default(autoincrement()) @id
writtenPost Post[] @relation("Post_authorToUser")
favoritedPosts Post[] @relation("Post_favoritedByToUser")
}
```

> **Warning**: Virtual relation fields that were renamed in the Prisma schema will be reset when you run `prisma introspect` again. You therefore might want to back up your Prisma schema with these attributes in order to not having to annotate everything from scratch again after a re-introspection.
Loading