diff --git a/content/200-concepts/100-components/01-prisma-schema/08-views.mdx b/content/200-concepts/100-components/01-prisma-schema/08-views.mdx index 8e869b043e..a202c719a6 100644 --- a/content/200-concepts/100-components/01-prisma-schema/08-views.mdx +++ b/content/200-concepts/100-components/01-prisma-schema/08-views.mdx @@ -11,7 +11,7 @@ tocDepth: 2 -Support for views is currently a very early preview feature. You can add a view to your Prisma schema with the `view` keyword, but you cannot introspect your schema with `db pull` or apply your schema to your database with Prisma Migrate and `db push`.

For updates on progress with this feature, follow [our GitHub issue](https://github.com/prisma/prisma/issues/17335). +Support for views is currently a very early [Preview](/about/prisma/releases#preview) feature. You can add a view to your Prisma schema with the `view` keyword or introspect the views in your database schema with `db pull`. You cannot yet apply views in your schema to your database with Prisma Migrate and `db push` unless the changes are added manually to your migration file using the `--create-only` flag.

For updates on progress with this feature, follow [our GitHub issue](https://github.com/prisma/prisma/issues/17335).
@@ -94,7 +94,7 @@ For a relational database, the SQL statement to create this view is: CREATE VIEW "UserInfo" AS SELECT u.id, email, name, bio FROM "User" u - LEFT JOIN "Profile" p ON u.id = p."userId" + LEFT JOIN "Profile" p ON u.id = p."userId"; ``` For MongoDB, you can [create a view](https://www.mongodb.com/docs/manual/core/views/join-collections-with-view/) with the following command: @@ -123,7 +123,7 @@ db.createView('UserInfo', 'User', [ ## Use views with Prisma Migrate and db push -If you apply changes to your schema with Prisma Migrate or `db push`, Prisma does not create or run any SQL related to views. +If you apply changes to your Prisma schema with Prisma Migrate or `db push`, Prisma does not create or run any SQL related to views. To include views in a migration, run `migrate dev --create-only` and then manually add the SQL for views to your migration file. Alternatively, you can create views manually in the database. @@ -140,7 +140,7 @@ You can represent the `UserInfo` view from the example above in your Prisma sche ```prisma view UserInfo { - id Int @id + id Int @unique email String name String bio String @@ -164,20 +164,148 @@ view UserInfo { -### Limitations +### Write by hand + +A `view` block is comprised of two main pieces: + +- The `view` block definition +- The view's field definitions + +These two pieces allow you to define the name of your view in the generated Prisma Client and the columns present in your view's query results. + +#### Define a `view` block -Currently, Prisma treats views in the same way as models. This means that a view needs to have a [unique identifier](/concepts/components/prisma-schema/data-model#defining-an-id-field). In relational databases, this can be an `@id` or `@unique` attribute on one field, or an `@@id` or `@@unique` attribute on multiple fields. In MongoDB, this must be an `@id` attribute that maps to the `_id` field in the underlying database with `@map("_id")`. +To define the `UserInfo` view from the example above, begin by using the `view` keyword to define a `view` block in your schema named `UserInfo`: + +```prisma +view UserInfo { + // Fields +} +``` -In the example above, the `id` field has an `@id` attribute. + + +#### Define fields + +The properties of a view are called _fields_, which consist of: + +- A field name +- A field type + +The fields of the `UserInfo` example view can be defined as follows: + +, ]}> + + +```prisma highlight=2-5;normal +view UserInfo { + id Int @unique + email String + name String + bio String +} +``` + + + + +```prisma highlight=2-5;normal +view UserInfo { + id String @id @default(auto()) @map("_id") @db.ObjectId + email String + name String + bio String +} +``` + + + -Prisma does not currently support introspection of views with `db pull`. Instead, you must manually add views to your Prisma schema. +Each _field_ of a `view` block represents a column in the query results of the view in the underlying database. + +### Use introspection + + +Currently only available for PostgreSQL. + + +If you have an existing view or views defined in your database, [introspection](/concepts/components/introspection) will automatically generate `view` blocks in your Prisma schema that represent those views. + +Assuming the example `UserInfo` view exists in your underlying database, running the following command will generate a `view` block in your Prisma schema representing that view: + +```sh copy +npx prisma db pull +``` + +The resulting `view` block will be defined as follows: + +```prisma +/// The underlying view does not contain a valid unique identifier and can therefore currently not be handled by the Prisma Client. +view UserInfo { + id Int? + email String? + name String? + bio String? + + @@ignore +} +``` + +The `view` block is generated initially with a `@@ignore` attribute because [there is no unique identifier defined](#unique-identifier) (which is currently a [limitation](#unique-identifier) of the views preview feature). + +In this view's case, the `id` column refers to a uniquely identifiable field in the underlying `User` table so that field will also be used as the uniquely identifiable field in the `view` block. + +In order to make this `view` block valid you will need to: + +- Remove the _optional_ flag `?` from the `id` field +- Add the `@unique` attribute to the `id` field +- Remove the `@@ignore` attribute +- Remove the comment Prisma generated warning about an invalid view + +```prisma highlight=4;add|1,3,8,9;delete +/// The underlying view does not contain a valid unique identifier and can therefore currently not be handled by the Prisma Client. +view UserInfo { + id Int? + id Int @unique + email String? + name String? + bio String? + + @@ignore +} +``` + +When re-introspecting your database, any custom changes to your view definitions will be preserved. -Currently, if you introspect your database, Prisma removes any existing `view` blocks in your schema file. To reinstate the views, you must revert this change. +Please note for now `db pull` will only introspect views in your schema when using PostgreSQL. Support for this workflow will be extended to other database providers soon. +### Limitations + +#### Unique Identifier + +Currently, Prisma treats views in the same way as models. This means that a view needs to have at least one _unique identifier_, which can be represented by any of the following: + +- A unique constraint denoted with [`@unique`](/concepts/components/prisma-schema/data-model#defining-a-unique-field) +- A composite unique constraint denoted with [`@@unique`](/concepts/components/prisma-schema/data-model#defining-a-unique-field) +- An [`@id`](/concepts/components/prisma-schema/data-model#defining-an-id-field) field +- A composite identifier denoted with [`@@id`](/concepts/components/prisma-schema/data-model#composite-ids) + +In relational databases, a view's unique identifier can be defined as a `@unique` attribute on one field, or a `@@unique` attribute on multiple fields. When possible, it is preferable to use a `@unique` or `@@unique` constraint over an `@id` or `@@id` field. + +In MongoDB, however, the unique identifier must be an `@id` attribute that maps to the `_id` field in the underlying database with `@map("_id")`. + +In the example above, the `id` field has a `@unique` attribute. If another column in the underlying `User` table had been defined as uniquely identifiable and made available in the view's query results, that column could have been used as the unique identifier instead. + +#### Introspection + +Currently, introspection of views is only available for PostgreSQL. If you are using another database provider, your views must be added manually. + +This is a temporary limitation and support for introspection will be extended soon to the other supported datasource providers. + ## Query views in Prisma Client You can query views in Prisma Client in the same way that you query models. For example, the following query finds all users with a `name` of `'Alice'` in the `UserInfo` view defined above.