From 93d2ad3d57ef09c3e3e12530bf07025fa88a8cc4 Mon Sep 17 00:00:00 2001 From: Nikolas Burk Date: Mon, 23 Mar 2020 11:04:58 +0100 Subject: [PATCH 1/8] continue docs --- .../20-database-polyfills.mdx | 13 ++ .../what-is-prisma-migrate.mdx | 204 ++++++++++++++++++ content/05-more/01-about-the-docs.mdx | 4 + 3 files changed, 221 insertions(+) create mode 100644 content/03-reference/01-tools-and-interfaces/02-prisma-client/20-database-polyfills.mdx diff --git a/content/03-reference/01-tools-and-interfaces/02-prisma-client/20-database-polyfills.mdx b/content/03-reference/01-tools-and-interfaces/02-prisma-client/20-database-polyfills.mdx new file mode 100644 index 0000000000..7ede15a3f4 --- /dev/null +++ b/content/03-reference/01-tools-and-interfaces/02-prisma-client/20-database-polyfills.mdx @@ -0,0 +1,13 @@ +--- +title: "Database polyfills" +metaTitle: "" +metaDescription: "" +--- + +## Overview + +Prisma Client provides features that are typically not achievable with relational databases. These features are referred to as _polyfills_. + +- Initializing [ID]() values with `cuid` and `uuid` values (requires [Prisma Migrate]()) +- [Making 1-1-relations required on both sides]() +- [Implicit many-to-many relations]() diff --git a/content/03-reference/01-tools-and-interfaces/03-prisma-migrate/what-is-prisma-migrate.mdx b/content/03-reference/01-tools-and-interfaces/03-prisma-migrate/what-is-prisma-migrate.mdx index e69de29bb2..0eea9f9378 100644 --- a/content/03-reference/01-tools-and-interfaces/03-prisma-migrate/what-is-prisma-migrate.mdx +++ b/content/03-reference/01-tools-and-interfaces/03-prisma-migrate/what-is-prisma-migrate.mdx @@ -0,0 +1,204 @@ +--- +title: "What is Prisma Migrate" +metaTitle: "" +metaDescription: "" +--- + +## Overview + +Prisma Migrate is a tool that lets you _change your database schema_, e.g. by creating new tables or adding columns to existing tables. These changes are called _schema migrations_. Prisma Migrate is available as part of the [Prisma CLI]() via the `prisma migrate` command. + +**Prisma Migrate is currently in an experimental state.** This means that it is not recommended to use Prisma Migrate in production. Instead, you can perform schema migrations using plain SQL or another migration tool of your choice and then bring the changes into your Prisma schema using [introspection](). + +## Prisma Migrate vs SQL migrations + +Prisma Migrate is a _declarative_ migration system, as opposed to SQL which can be considered _imperative_: + +- **SQL (imperative)**: Provide the individual _steps_ to get from the current schema to the desired schema. +- **Prisma Migrate (delarative)**: Define the desired schema as a [Prisma data model]() (Prisma Migrate takes care of generating the necessary _steps_). + +Here's a quick comparison. Assume you have the following scenario: + +1. You need to create `User` table to store user information (name, email, ...) +1. Create two new tables `Post` and `Profile` with foreign keys to `User` +1. Add a new column with default value to the `Post` table + +### SQL + +In SQL, you'd have to send three subsequent SQL statements to account for this scenario: + +**1. Create `User` table to store user information (name, email, ...)** + +```sql +CREATE TABLE "User" ( + id SERIAL PRIMARY KEY, + name VARCHAR(255), + email VARCHAR(255) NOT NULL +); +``` + +**2. Create two new tables `Post` and `Profile` with foreign keys to `User`** + +```sql +CREATE TABLE "Profile" ( + id SERIAL PRIMARY KEY, + bio TEXT NOT NULL, + "user" integer NOT NULL UNIQUE, + FOREIGN KEY ("user") REFERENCES "User"(id) +); +CREATE TABLE "Post" ( + id SERIAL PRIMARY KEY, + title VARCHAR(255) NOT NULL, + author integer NOT NULL, + FOREIGN KEY (author) REFERENCES "User"(id) +); +``` + +**3. Add a new column with default value to the `Post` table** + +```sql +ALTER TABLE "Post" +ADD COLUMN published BOOLEAN DEFAULT false; +``` + +### Prisma Migrate + +With Prisma Migrate, you write the desired database schema in the form of a [Prisma data model]() in your [Prisma schema file](). To map the data model to your database schema, you then have to run these two commands: + +``` +prisma migrate save --experimental +prisma migrate up --experimental +``` + +The first command _saves_ a new migration to the file system and updates the [`_Migration`]() table. The second command _executes_ the migration against your database. + +Note that `prisma migrate save` stores information about the migration in a dedicated directory inside the [`migrations`]() directory. Each migration that is stored has its own `README.md` file which contains detailled information about the migration (e.g. the generated SQL statements which will be executed when you run `prisma migrate up`). + +**1. Create `User` table to store user information (name, email, ...)** + +Add a model to your Prisma schema: + +```prisma +model User { + id Int @id @default(autoincrement()) + name String? + email String @unique +} +``` + +Now run the two commands mentioned above: + +``` +prisma migrate save --experimental +prisma migrate up --experimental +``` + +**2. Create two new tables `Post` and `Profile` with foreign keys to `User`** + +Add two models with [relation fields]() to your Prisma schema: + +```prisma +model User { + id Int @id @default(autoincrement()) + name String? + email String @unique + posts Post[] + profile Profile? +} + +model Profile { + id Int @id @default(autoincrement()) + bio String + user User +} + +model Post { + id Int @id @default(autoincrement()) + title String + author User +} +``` + +Notice that in addition to the [relation fields which represent the foreign keys](), you also must specify the [virtual relation fields]() on the other side of the relation. + +Now run the two commands mentioned above: + +``` +prisma migrate save --experimental +prisma migrate up --experimental +``` + +**3. Add a new column with default value to the `Post` table** + +Add a [field]() to the `Post` model: + +```prisma +model User { + id Int @id @default(autoincrement()) + name String? + email String @unique + posts Post[] + profile Profile? +} + +model Profile { + id Int @id @default(autoincrement()) + bio String + user User +} + +model Post { + id Int @id @default(autoincrement()) + title String + published Boolean @default(false) + author User +} +``` + +Now run the two commands mentioned above: + +``` +prisma migrate save --experimental +prisma migrate up --experimental +``` + +## Supported operations + +The following table shows which SQL operations are currently supported by Prisma Migrate. If an operation is not yet supported, it links to a workaround that uses plain SQL and [introspection]() to enable this feature in Prisma Client. + +| Operation | SQL | Supported | +| :---------------------------------- | :------------------------------ | :----------------------: | +| Create a new table | `CREATE TABLE` | ✔️ | +| Rename an existing table | `ALTER TABLE` + `RENAME` | Not yet ([workaround]()) | +| Delete an existing table | `DROP TABLE` | ✔️ | +| Add a column to an existing table | `ALTER TABLE` + `ADD COLUMN` | ✔️ | +| Rename an existing column | `ALTER TABLE` + `RENAME COLUMN` | Not yet ([workaround]()) | +| Delete an existing column | `ALTER TABLE` + `DROP COLUMN` | ✔️ | +| Set primary keys ([IDs]()) | `PRIMARY KEY` | ✔️ | +| Define [relations]() (foreign keys) | `FOREIGN KEY` + `REFERENCES` | ✔️ | +| Make columns [optional/required]() | `NOT NULL` | ✔️ | +| Set [unique constraints]() | `UNIQUE` | ✔️ | +| Set [default]() values | `DEFAULT` | ✔️ | +| Defining [enums]() | `ENUM` | ✔️ | +| Create [indexes]() | `CREATE INDEX` | ✔️ | +| Cascading deletes | `ON DELETE` | Not yet ([workaround]()) | +| Cascading updates | `ON UPDATE` | Not yet ([workaround]()) | +| Data validation | `CHECK` | Not yet ([workaround]()) | + +Note that this table assumes that the operation is also supported by the underlying database. For example, `ENUM` is not supported in SQLite, this means that you also can't use `enum` using Prisma Migrate. + +## CLI + +## Polyfills + +Prisma Migrate provides features that are typically not achievable with relational databases. These features are referred to as _polyfills_. + +- Initializing [ID]() values with `cuid` and `uuid` values (requires [Prisma Migrate]()) +- [Making 1-1-relations required on both sides]() +- [Implicit many-to-many relations]() + +## Migration history + +### The `migrations` directory + +### The `_Migration` table \ No newline at end of file diff --git a/content/05-more/01-about-the-docs.mdx b/content/05-more/01-about-the-docs.mdx index ff2ececf9f..fb19e4f36d 100644 --- a/content/05-more/01-about-the-docs.mdx +++ b/content/05-more/01-about-the-docs.mdx @@ -11,3 +11,7 @@ Coming 🔜 ## The `User` and `Post` data model `User` and `Post` are the canonical models that are being used throughout the Prisma docs. This page gives some context on why these have been selected and how to interpret them. + +## Naming conventions for tables and columns + +Table names are generally spelled in [PascalCase](). Column names in [camelCase](). \ No newline at end of file From e762cadc867bec6b84688c1dcd91647f46982cf7 Mon Sep 17 00:00:00 2001 From: Nikolas Burk Date: Mon, 23 Mar 2020 11:32:29 +0100 Subject: [PATCH 2/8] continue docs --- ...rate.mdx => 01-what-is-prisma-migrate.mdx} | 21 +++++++++++++------ .../03-prisma-migrate/migration-scenarios.mdx | 0 2 files changed, 15 insertions(+), 6 deletions(-) rename content/03-reference/01-tools-and-interfaces/03-prisma-migrate/{what-is-prisma-migrate.mdx => 01-what-is-prisma-migrate.mdx} (84%) delete mode 100644 content/03-reference/01-tools-and-interfaces/03-prisma-migrate/migration-scenarios.mdx diff --git a/content/03-reference/01-tools-and-interfaces/03-prisma-migrate/what-is-prisma-migrate.mdx b/content/03-reference/01-tools-and-interfaces/03-prisma-migrate/01-what-is-prisma-migrate.mdx similarity index 84% rename from content/03-reference/01-tools-and-interfaces/03-prisma-migrate/what-is-prisma-migrate.mdx rename to content/03-reference/01-tools-and-interfaces/03-prisma-migrate/01-what-is-prisma-migrate.mdx index 0eea9f9378..c883a49acd 100644 --- a/content/03-reference/01-tools-and-interfaces/03-prisma-migrate/what-is-prisma-migrate.mdx +++ b/content/03-reference/01-tools-and-interfaces/03-prisma-migrate/01-what-is-prisma-migrate.mdx @@ -63,16 +63,16 @@ ADD COLUMN published BOOLEAN DEFAULT false; ### Prisma Migrate -With Prisma Migrate, you write the desired database schema in the form of a [Prisma data model]() in your [Prisma schema file](). To map the data model to your database schema, you then have to run these two commands: +With Prisma Migrate, you write the desired database schema in the form of a [Prisma data model]() inside your [Prisma schema file](). To map the data model to your database schema, you then have to run these two commands: ``` prisma migrate save --experimental prisma migrate up --experimental ``` -The first command _saves_ a new migration to the file system and updates the [`_Migration`]() table. The second command _executes_ the migration against your database. +The first command _saves_ a new migration to the file system and updates the [`_Migration`]() table. It stores information about the migration in a dedicated directory inside the [`migrations`]() directory. Each migration that is stored has its own `README.md` file which contains detailled information about the migration (e.g. the generated SQL statements which will be executed when you run `prisma migrate up`). -Note that `prisma migrate save` stores information about the migration in a dedicated directory inside the [`migrations`]() directory. Each migration that is stored has its own `README.md` file which contains detailled information about the migration (e.g. the generated SQL statements which will be executed when you run `prisma migrate up`). +The second command _executes_ the migration against your database. **1. Create `User` table to store user information (name, email, ...)** @@ -187,8 +187,6 @@ The following table shows which SQL operations are currently supported by Prisma Note that this table assumes that the operation is also supported by the underlying database. For example, `ENUM` is not supported in SQLite, this means that you also can't use `enum` using Prisma Migrate. -## CLI - ## Polyfills Prisma Migrate provides features that are typically not achievable with relational databases. These features are referred to as _polyfills_. @@ -199,6 +197,17 @@ Prisma Migrate provides features that are typically not achievable with relation ## Migration history +Prisma Migrate stores the migration history of your project in two places: + +- A directory called `migrations` on your file system +- A table called `_Migrations` in your database + ### The `migrations` directory -### The `_Migration` table \ No newline at end of file +The `migrations` directory stores information about the migrations that have been or will be executed against your database. You should never make any manual changes to the files in `migrations`, the only way to change the content of this directory should be using the `prisma migrate save` command. + +The `migrations` directory should be checked into version control (e.g. Git). + +### The `_Migrations` table + +The `_Migrations` table additionally stores information about each migration that was ever executed against the database by Prisma Migrate. \ No newline at end of file diff --git a/content/03-reference/01-tools-and-interfaces/03-prisma-migrate/migration-scenarios.mdx b/content/03-reference/01-tools-and-interfaces/03-prisma-migrate/migration-scenarios.mdx deleted file mode 100644 index e69de29bb2..0000000000 From 5bdebb048a7bdf2411e8af50a73e9dc44086b341 Mon Sep 17 00:00:00 2001 From: Nikolas Burk Date: Mon, 23 Mar 2020 13:41:51 +0100 Subject: [PATCH 3/8] continue docs --- .../04-type-mappings.mdx | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 content/03-reference/02-database-connectors/04-type-mappings.mdx diff --git a/content/03-reference/02-database-connectors/04-type-mappings.mdx b/content/03-reference/02-database-connectors/04-type-mappings.mdx new file mode 100644 index 0000000000..5807e513cd --- /dev/null +++ b/content/03-reference/02-database-connectors/04-type-mappings.mdx @@ -0,0 +1,101 @@ +--- +title: 'Type mappings' +metaTitle: '' +metaDescription: '' +--- + +## PostgreSQL + +| Postgres Type | Prisma Type | Currently | w/o Native Types | For launch | Comment | +|---------------------------------------------------------------------------------------------------|-------------|-----------|------------------|------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| smallint \| int2 | Int | Yes | No | Yes | | +| "integer \| int, int4" | Int | Yes | No | Yes | | +| bigint \| int8 | Int | Yes | No | Yes | | +| "numeric(p,s) \| decimal(p,s)" | Float | Yes | No | Yes | Could introduce Decimal type in the future. | +| "real \| float, float4" | Float | Yes | No | Yes | | +| double precision \| float8 | Float | Yes | No | Yes | | +| smallserial \| serial2 | Int | Yes | No | Yes | Automatically creates a sequence | +| serial \| serial4 | Int | Yes | No | Yes | Automatically creates a sequence | +| bigserial \| serial8 | Int | Yes | No | Yes | Automatically creates a sequence | +| money | Float | No | Yes | Yes | "Only stores 2 decimal points, silently truncates" | +| character(n) \| char(n) | String | Yes | No | Yes | | +| character varying(n) \| varchar(n) | String | Yes | No | Yes | | +| text | String | Yes | No | Yes | | +| bytea | | No | No | No | "Most likely, our character set of choice (UTF8) is not able to express all characters possible, leading to data loss issues if people load a binary value and save it again. We should probably not convert this to String type." | +| timestamp without time zone \| timestamp | DateTime | Yes | No | Yes | Silently truncates a provided time zone | +| timestamp with time zone \| timestamptz | DateTime | Yes | No | Yes | Silently adds local time zone if not provided | +| date | DateTime | Yes | No | Yes | Silently truncates provided time component | +| time without time zone \| time | DateTime | Yes | No | Yes | Silently truncates date and time zone components | +| time with time zone \| timetz | DateTime | Yes | No | Yes | Silently truncates date component. Adds local time zone if missing | +| interval | String | No | Yes | No | Will fail if inserting a malformed string: invalid input syntax for type interval | +| boolean \| bool | Bool | Yes | No | Yes | | +| enum | Enum | Yes | No | Yes | | +| point | | No | No | No | Doesn't map cleanly to our current types. | +| line | | No | No | No | Doesn't map cleanly to our current types. | +| lseg | | No | No | No | Doesn't map cleanly to our current types. | +| box | | No | No | No | Doesn't map cleanly to our current types. | +| path | | No | No | No | Doesn't map cleanly to our current types. | +| polygon | | No | No | No | Doesn't map cleanly to our current types. | +| circle | | No | No | No | Doesn't map cleanly to our current types. | +| cidr | String | No | Yes | No | input and output is string. will error on malformed data. | +| inet | String | No | Yes | Yes | input and output is string. will error on malformed data. subnet component is silently truncated | +| macaddr | String | No | Yes | No | input and output is string. will error on malformed data. | +| bit(n) | String | No | Yes | Yes | input and output is string (e.g. 1011). will error on malformed data. Will error if the string is not the exact length n. | +| bit varying(n) | String | No | Yes | Yes | input and output is string. will error on malformed data. Will error if string is longer than n. | +| tsvector | String | No | Yes | No | "Accepts a string. Each word is turned into a list item in quotes. The following statements are equivalent. quoted: UPDATE ""public"".""types"" SET ""tsvector""='''a'' ''dump'' ''dumps'' ''fox'' ''in'' ''the''' WHERE ""id""=1 RETURNING ""tsvector""; unquoted: UPDATE ""public"".""types"" SET ""tsvector""='a fox dumps in the dump' WHERE ""id""=1 RETURNING ""tsvector""; and both result in the stored value being 'a' 'dump' 'dumps' 'fox' 'in' 'the'. For this reason we need to support double quoting by turning 'a' 'dump' 'dumps' 'fox' 'in' 'the' into '''a'' ''dump'' ''dumps'' ''fox'' ''in'' ''the''' during data insertion." | +| tsquery | String | No | Yes | No | "Inserted data must be double quoted. works: SET ""tsquery""='''foxy cat''' doesn't work: SET ""tsquery""='foxy cat'. The returned value is also quoted, so we can probably make this work without the Query Engine having specific knowledge of tsquery" | +| uuid | String | No | Yes | Yes | String in and out. Accepts different formatting and always returns a standard format. Will error if input is malformed | +| xml | | No | No | No | "Postgres requires wrapping syntax on input, so we cannot treat it as string: 'bar'::xml. Also, does not support comparison." | +| json | String | No | Yes | Yes | "text in and out. Will complain if malformed. Example: {""a"": 3}" | +| jsonb | String | No | Yes | Yes | "text in and out. Will complain if malformed. Example: {""a"": 3}" | +| Array types | | Yes | No | Yes | We simply treat this as a https://github.com/prisma/prisma2/blob/master/docs/data-modeling.md#type-modifiers for any of our scalar types. This is implemented and works | +| Composite types | | No | No | No | We don't support this | +| "oid \| regproc, regprocedure, regoper, regoperator, regclass, regtype, regconfig, regdictionary" | Int | No | Yes | No | "Integer in and out. Will return OID out of range if too big, and overflow if negative." | +| int4range | String | No | Yes | No | "String in and out. Complains if malformed. Example: [2,3)" | +| int8range | String | No | Yes | No | String in and out. Complains if malformed. | +| numrange | String | No | Yes | No | String in and out. Complains if malformed. | +| tsrange | String | No | Yes | No | String in and out. Complains if malformed. | +| tstzrange | String | No | Yes | No | String in and out. Complains if malformed. | +| daterange | String | No | Yes | No | String in and out. Complains if malformed. | +| Domain types | | No | No | No | We don't support this | + + +## MySQL + +| MySQL Type | Prisma Type | Currently | w/o Native Types | For launch | Comment | +|----------------------|-------------|-----------|------------------|------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| smallint | Int | Yes | No | Yes | | +| int | Int | Yes | No | Yes | | +| bigint | Int | Yes | No | Yes | Can we hold the full range? | +| decimal | Float | Yes | No | Yes | Can we hold the full range of the biggest possible range? Do we need a dedicated Decimal value? | +| float | Float | Yes | No | Yes | | +| double | Float | Yes | No | Yes | Can we hold the full range? | +| bit | Int | No | Yes | Yes | "MySQL performs normal Int ↔ bit conversion: 1 → 1, 2 → 10, 3 → 11 ..." | +| boolean / tinyint(1) | Bool | Yes | No | Yes | | +| date | DateTime | No | Yes | Yes | Rely on MySQL conversion | +| datetime | DateTime | Yes | Yes | Yes | | +| timestamp | DateTime | No | Yes | Yes | https://stackoverflow.com/questions/31761047/what-difference-between-the-date-time-datetime-and-timestamp-types/56138746 datetime and timestamp takes the same format. They have different ranges and treat time zones differently. | +| time | DateTime | No | Yes | Yes | MySQL simply strips the date component. When reading the data we will need to be able to turn it into a DateTime either in QE or Client. | +| year | Int | No | Yes | Yes | MySQL will return error if out of range (1901 to 2155) Funky conversion rules: https://dev.mysql.com/doc/refman/8.0/en/year.html | +| char | String | Yes | No | Yes | MySQL will silently truncate or return error if inserting long string | +| varchar | String | Yes | No | Yes | MySQL will silently truncate or return error if inserting long string | +| tinytext | String | Yes | No | Yes | MySQL will silently truncate or return error if inserting long string | +| text | String | Yes | No | Yes | MySQL will silently truncate or return error if inserting long string | +| mediumtext | String | Yes | No | Yes | MySQL will silently truncate or return error if inserting long string | +| longtext | String | Yes | No | Yes | MySQL will silently truncate or return error if inserting long string | +| binary | | No | No | No | "Conversion might behave in unexpected ways for the user: http://www.ovaistariq.net/632/understanding-mysql-binary-and-non-binary-string-data-types/#.XlWQtBNKjUI Most likely, our character set of choice (UTF8) is not able to express all characters possible, leading to data loss issues if people load a binary value and save it again. We should probably not convert this to String type. " | +| varbinary | String | No | No | No | Conversion might behave in unexpected ways for the user: http://www.ovaistariq.net/632/understanding-mysql-binary-and-non-binary-string-data-types/#.XlWQtBNKjUI | +| tinyblob | String | No | No | No | Conversion might behave in unexpected ways for the user: http://www.ovaistariq.net/632/understanding-mysql-binary-and-non-binary-string-data-types/#.XlWQtBNKjUI | +| mediumblob | String | No | No | No | Conversion might behave in unexpected ways for the user: http://www.ovaistariq.net/632/understanding-mysql-binary-and-non-binary-string-data-types/#.XlWQtBNKjUI | +| blob | String | No | No | No | Conversion might behave in unexpected ways for the user: http://www.ovaistariq.net/632/understanding-mysql-binary-and-non-binary-string-data-types/#.XlWQtBNKjUI | +| enum | Enum | Yes | No | Yes | | +| set | | No | No | No | Doesn't map cleanly to our current types. https://dev.mysql.com/doc/refman/8.0/en/set.html | +| geometry | | No | No | No | Doesn't map cleanly to our current types. | +| point | | No | No | No | Doesn't map cleanly to our current types. | +| linestring | | No | No | No | Doesn't map cleanly to our current types. | +| polygon | | No | No | No | Doesn't map cleanly to our current types. | +| multipoint | | No | No | No | Doesn't map cleanly to our current types. | +| multilinestring | | No | No | No | Doesn't map cleanly to our current types. | +| multipolygon | | No | No | No | Doesn't map cleanly to our current types. | +| geometrycollection | | No | No | No | Doesn't map cleanly to our current types. | +| json | String | Yes | No | Yes | https://github.com/prisma/prisma2-private/issues/22 | From 844bc4d5c6f9941cd19a8b7367384ad6057f3ba2 Mon Sep 17 00:00:00 2001 From: Nikolas Burk Date: Mon, 23 Mar 2020 15:55:40 +0100 Subject: [PATCH 4/8] continue docs --- .../02-start-from-scratch-sql-migrations.mdx | 2 +- .../02-database-connectors/01-postgresql.mdx | 109 +++++++++++++++++- .../04-connection-urls.mdx | 35 ++++++ 3 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 content/03-reference/02-database-connectors/04-connection-urls.mdx diff --git a/content/01-getting-started/03-setup-prisma/02-start-from-scratch-sql-migrations.mdx b/content/01-getting-started/03-setup-prisma/02-start-from-scratch-sql-migrations.mdx index 8a1d841795..2d66bf2f41 100644 --- a/content/01-getting-started/03-setup-prisma/02-start-from-scratch-sql-migrations.mdx +++ b/content/01-getting-started/03-setup-prisma/02-start-from-scratch-sql-migrations.mdx @@ -18,7 +18,7 @@ In order to successfully complete this guide, you need: Make sure your have your database [connection URL]() (includes your authentication credentials) at hand! -If you don't have a database server running and only want to explore Prisma, check out the [Quickstart](). +If you don't have a database server running and only want to explore Prisma, check out the [Quickstart](). Alternatively you can [setup a free PostgreSQL database on Heroku](https://dev.to/prisma/how-to-setup-a-free-postgresql-database-on-heroku-1dc1) and use it in this guide. ## Create project setup diff --git a/content/03-reference/02-database-connectors/01-postgresql.mdx b/content/03-reference/02-database-connectors/01-postgresql.mdx index e73dd09535..13db303388 100644 --- a/content/03-reference/02-database-connectors/01-postgresql.mdx +++ b/content/03-reference/02-database-connectors/01-postgresql.mdx @@ -4,4 +4,111 @@ metaTitle: '' metaDescription: '' --- -Coming 🔜 +## Overview + +The PostgreSQL data source connector connects Prisma to a [PostgreSQL]() database server. + +## Example + +To connect to a PostgreSQL database server, you need to configure a [`datasource`]() block in your [Prisma schema file](): + + +```prisma +datasource postgresql { + provider = "postgresql" + url = env("DATABASE_URL") +} +``` + +The fields passed to the `datasource` block are: + +- `provider`: Specifies the `postgresql` data source connector. +- `url`: Specifies the [connection URL](#connection-url) for the PostgreSQL database server. In this case, an [environment variable is used](../../prisma-schema-file.md#using-environment-variables) to provide the connection URL. + +## Data model mapping + +The PostgreSQL connector maps the [scalar types](../../data-modeling.md#scalar-types) from the [data model](../../data-modeling.md#scalar-types) as follows to native column types: + +### Introspection + +### Prisma Migrate + +## Connection details + +### Connection string + +PostgreSQL offers two styles of connection strings: + +- Key-value string: `host=localhost port=5432 database=mydb connect_timeout=10` +- Connection URI: + ``` + postgresql:// + postgresql://localhost + postgresql://localhost:5433 + postgresql://localhost/mydb + postgresql://user@localhost + postgresql://user:secret@localhost + postgresql://other@localhost/otherdb?connect_timeout=10&application_name=myapp + postgresql://host1:123,host2:456/somedb?target_session_attrs=any&application_name=myapp + ``` + +See the [official documentation](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING) for details. + +The connection URI needs to follow the [official format](https://www.postgresql.org/docs/10/libpq-connect.html#id-1.7.3.8.3.6) for PostgreSQL connection strings: + +``` +postgresql://[user[:password]@][netloc][:port][,...][/database][?param1=value1&...] +``` + +### Configuration options + +- `host`: The IP address/domain of your database server, e.g. `localhost`. +- `port`: The port on which your database server listens, e.g. `5432`. +- `database`: The name of the database with the target schema. +- `schema`: The name of the target schema. **Default**: `public`. +- `user`: The database user, e.g. `admin`. +- `password`: The password for the database user. +- `connection_limit`: The connection limit specifies the maximum number of simultaneous connections that Prisma might have open to your database. The **default value** is calculated according to this formula: `num_physical_cpus * 2 + 1`. +- `connect_timeout`: The maximum number of seconds to wait for a new connection. **Default**: `5`. +- `socket_timeout`: The maximum number of seconds to wait until a single query terminates. **Default**: `5`. + +See the next section to learn how you can configure an SSL connection. + +### Configuring an SSL connection + +You can add various parameters to the connection string if your database server uses SSL. Here's an overview of the possible parameters: + +- `sslmode=(disable|prefer|require)`: + - `prefer` (default): Prefer TLS if possible, accept plain text connections. + - `disable`: Do not use TLS. + - `require`: Require TLS or fail if not possible. +- `sslcert=`: Path the the server certificate. This is the root certificate used by the database server to sign the client certificate. You need to provide this if the certificate doesn't exist in the trusted certificate store of your system. For Google Cloud this likely is `server-ca.pem`. +- `sslidentity=`: Path to the PKCS12 certificate database created from client cert and key. This is the SSL identity file in PKCS12 format which you will generate using the client key and client certificate. It combines these two files in a single file and secures them via a password (see next parameter). You can create this file using your client key and client certificate by using the following command (using `openssl`): + ``` + openssl pkcs12 -export -out client-identity.p12 -inkey client-key.pem -in client-cert.pem + ``` +- `sslpassword=`: Password that was used to secure the PKCS12 file. The `openssl` command listed in the previous step will ask for a password while creating the PKCS12 file, you will need to provide that same exact password here. +- `sslaccept=(strict|accept_invalid_certs)`: + - `strict`: Any missing value in the certificate will lead to an error. For Google Cloud, especially if the database doesn't have a domain name, the certificate might miss the domain/IP address, causing an error when connecting. + - `accept_invalid_certs` (default): Bypass this check. Be aware of the security consequences of this setting. + +To recap, in order to create a SSL connection to your database, you need: + +- A root [CA](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc778623(v=ws.10)?redirectedfrom=MSDN) file +- A [PKCS12](https://en.wikipedia.org/wiki/PKCS_12) client file +- A [PKCS12](https://en.wikipedia.org/wiki/PKCS_12) password + +Your database connection URL will look similar to this: + +``` +postgresql://user:password@host?sslidentity=client-identity.p12&sslpassword=mypassword&sslcert=rootca.cert +``` + +### Connecting via sockets + +To connect to your PostgreSQL database via sockets, you must add a `host` field as a _query parameter_ to the connection string (instead of setting it as the `host` part of the URI). +The value of this parameter then must point to the directory that contains the socket, e.g.: +`postgresql://user:password@localhost/database?host=/var/run/postgresql/` +Note that `localhost` is required, the value itself is ignored and can be anything. + +Learn more in this [GitHub issue](https://github.com/prisma/prisma-client-js/issues/437#issuecomment-592436707). \ No newline at end of file diff --git a/content/03-reference/02-database-connectors/04-connection-urls.mdx b/content/03-reference/02-database-connectors/04-connection-urls.mdx new file mode 100644 index 0000000000..412b22caa1 --- /dev/null +++ b/content/03-reference/02-database-connectors/04-connection-urls.mdx @@ -0,0 +1,35 @@ +--- +title: 'Connection URLs' +metaTitle: '' +metaDescription: '' +--- + +## Overview + +Prisma needs a connection URL to be able to connect to your database, e.g. when sending queries with [Prisma Client]() or when changing the database schema with [Prisma Migrate](). + +The connection URL is provided via the `url` field of a `datasource` block in your Prisma schema. It generally consists of the following components (except for SQLite): + +- **User**: The name of your database user +- **Password**: The password for your database user +- **Host**: The IP or domain name of the machine where your database server is running +- **Port**: The port on which your database server is running +- **Database name**: The name of the database you want to use + +Make sure you have this information at hand when getting started with Prisma. If you don't have a database server running yet, you can either use a local SQLite database file (see the [Quickstart]()) or [setup a free PostgreSQL database on Heroku](https://dev.to/prisma/how-to-setup-a-free-postgresql-database-on-heroku-1dc1). + +Here is an example for a local PostgreSQL database: + +```prisma +dataource postgresql { + provider = "postgresql" + url = "postgresql://janedoe:mypassword@localhost:5432/mydb" +} +``` + +## Format + +The format of the connection URL depends on the _database connector_ you're using. Prisma supports the standard formats for each database. + +https://www.postgresql.org/docs/current/libpq-connect.html#id-1.7.3.8.3.6 +https://www.sqlite.org/c3ref/open.html \ No newline at end of file From 97993a67b85d0348fdd2cae6c25d435c6ac54688 Mon Sep 17 00:00:00 2001 From: Nikolas Burk Date: Mon, 23 Mar 2020 16:28:15 +0100 Subject: [PATCH 5/8] continue docs --- content/03-reference/02-database-connectors/01-postgresql.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/03-reference/02-database-connectors/01-postgresql.mdx b/content/03-reference/02-database-connectors/01-postgresql.mdx index 13db303388..3eb4fca259 100644 --- a/content/03-reference/02-database-connectors/01-postgresql.mdx +++ b/content/03-reference/02-database-connectors/01-postgresql.mdx @@ -35,7 +35,7 @@ The PostgreSQL connector maps the [scalar types](../../data-modeling.md#scalar-t ## Connection details -### Connection string +### Connection URL PostgreSQL offers two styles of connection strings: From 1293ff0d81aeb0ead673788537b305e7e02ca85c Mon Sep 17 00:00:00 2001 From: Nikolas Burk Date: Mon, 23 Mar 2020 20:08:39 +0100 Subject: [PATCH 6/8] continue docs --- .../02-database-connectors/01-postgresql.mdx | 191 ++++++++++++----- .../02-database-connectors/02-mysql.mdx | 195 +++++++++++++++++- .../02-database-connectors/03-sqlite.mdx | 62 +++++- .../04-connection-urls.mdx | 1 + .../07-data-validation/index.mdx | 2 +- 5 files changed, 401 insertions(+), 50 deletions(-) diff --git a/content/03-reference/02-database-connectors/01-postgresql.mdx b/content/03-reference/02-database-connectors/01-postgresql.mdx index 3eb4fca259..042ff4e2b9 100644 --- a/content/03-reference/02-database-connectors/01-postgresql.mdx +++ b/content/03-reference/02-database-connectors/01-postgresql.mdx @@ -12,7 +12,6 @@ The PostgreSQL data source connector connects Prisma to a [PostgreSQL]() databas To connect to a PostgreSQL database server, you need to configure a [`datasource`]() block in your [Prisma schema file](): - ```prisma datasource postgresql { provider = "postgresql" @@ -23,92 +22,190 @@ datasource postgresql { The fields passed to the `datasource` block are: - `provider`: Specifies the `postgresql` data source connector. -- `url`: Specifies the [connection URL](#connection-url) for the PostgreSQL database server. In this case, an [environment variable is used](../../prisma-schema-file.md#using-environment-variables) to provide the connection URL. +- `url`: Specifies the [connection URL](#connection-url) for the PostgreSQL database server. In this case, an [environment variable is used]() to provide the connection URL. -## Data model mapping +## Connection details -The PostgreSQL connector maps the [scalar types](../../data-modeling.md#scalar-types) from the [data model](../../data-modeling.md#scalar-types) as follows to native column types: +### Connection URL -### Introspection +Prisma follows the [official PostgreSQLl format](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING) for connection URLs. Here's an overview of the components needed for a PostgreSQL connection URL: -### Prisma Migrate +![](https://imgur.com/ZMzozDQ.png) -## Connection details +**Base URL and path** -### Connection URL +Here is an example of the structure of the _base URL_ and the _path_ using placeholder values in uppercase letters: -PostgreSQL offers two styles of connection strings: +``` +postgresql://USER:PASSWORD@HOST:PORT/DATABASE +``` -- Key-value string: `host=localhost port=5432 database=mydb connect_timeout=10` -- Connection URI: - ``` - postgresql:// - postgresql://localhost - postgresql://localhost:5433 - postgresql://localhost/mydb - postgresql://user@localhost - postgresql://user:secret@localhost - postgresql://other@localhost/otherdb?connect_timeout=10&application_name=myapp - postgresql://host1:123,host2:456/somedb?target_session_attrs=any&application_name=myapp - ``` +The following components make up the _base URL_ of your database, they are always required: -See the [official documentation](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING) for details. +| Name | Placeholder | Description | +| :------- | :---------- | :---------------------------------------------------------- | +| Host | `HOST` | IP address/domain of your database server, e.g. `localhost` | +| Port | `PORT` | Port on which your database server is running, e.g. `5432` | +| User | `USER` | Name of your database user, e.g. `janedoe` | +| Password | `PASSWORD` | Password for your database user | +| Database | `DATABASE` | Name of the [database]() you want to use, e.g. `mydb` | -The connection URI needs to follow the [official format](https://www.postgresql.org/docs/10/libpq-connect.html#id-1.7.3.8.3.6) for PostgreSQL connection strings: +**Arguments** + +A connection URL can also take arguments. Here is the same example from above with placeholder values in uppercase letters for three _arguments_: ``` -postgresql://[user[:password]@][netloc][:port][,...][/database][?param1=value1&...] +postgresql://USER:PASSWORD@HOST:PORT/DATABASE?KEY1=VALUE&KEY2=VALUE&KEY3=VALUE ``` -### Configuration options +The following arguments can be used + +| Argument name | Required | Default | Description | +| :----------------- | :------- | ---------------------- | ------------------------------------------------------------------------------ | +| `schema` | **Yes** | `public` | Mame of the schema you want to use, e.g. `myschema` | +| `connection_limit` | No | `num_cpus * 2 + 1` | Maximum size of the [connection pool]() | +| `connect_timeout` | No | `5` | Maximum number of seconds to wait for a new connection | +| `socket_timeout` | No | `5` | Maximum number of seconds to wait until a single query terminates | +| `sslmode` | No | `prefer` | Configures whether to use TLS, possible values: `prefer`, `disable`, `require` | +| `sslcert` | No | | Path the the server certificate | +| `sslidentity` | No | | Path to the PKCS12 certificate | +| `sslpassword` | No | | Password that was used to secure the PKCS12 file | +| `sslaccept` | No | `accept_invalid_certs` | Configures whether to check for missing values in the certificate | +| `host` | No | | Points to a directory that contains a socket to be used for the connection | -- `host`: The IP address/domain of your database server, e.g. `localhost`. -- `port`: The port on which your database server listens, e.g. `5432`. -- `database`: The name of the database with the target schema. -- `schema`: The name of the target schema. **Default**: `public`. -- `user`: The database user, e.g. `admin`. -- `password`: The password for the database user. -- `connection_limit`: The connection limit specifies the maximum number of simultaneous connections that Prisma might have open to your database. The **default value** is calculated according to this formula: `num_physical_cpus * 2 + 1`. -- `connect_timeout`: The maximum number of seconds to wait for a new connection. **Default**: `5`. -- `socket_timeout`: The maximum number of seconds to wait until a single query terminates. **Default**: `5`. +As an example, if you want to connect to a schema called `myschema`, set the connection pool size to `5` and configure a timeout for queries of `3` seconds, you can use the following arguments: -See the next section to learn how you can configure an SSL connection. +``` +postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=myschema&connection_limit=5&socket_timeout=3 +``` ### Configuring an SSL connection You can add various parameters to the connection string if your database server uses SSL. Here's an overview of the possible parameters: -- `sslmode=(disable|prefer|require)`: - - `prefer` (default): Prefer TLS if possible, accept plain text connections. +- `sslmode=(disable|prefer|require)`: + - `prefer` (default): Prefer TLS if possible, accept plain text connections. - `disable`: Do not use TLS. - `require`: Require TLS or fail if not possible. - `sslcert=`: Path the the server certificate. This is the root certificate used by the database server to sign the client certificate. You need to provide this if the certificate doesn't exist in the trusted certificate store of your system. For Google Cloud this likely is `server-ca.pem`. - `sslidentity=`: Path to the PKCS12 certificate database created from client cert and key. This is the SSL identity file in PKCS12 format which you will generate using the client key and client certificate. It combines these two files in a single file and secures them via a password (see next parameter). You can create this file using your client key and client certificate by using the following command (using `openssl`): - ``` - openssl pkcs12 -export -out client-identity.p12 -inkey client-key.pem -in client-cert.pem - ``` + ``` + openssl pkcs12 -export -out client-identity.p12 -inkey client-key.pem -in client-cert.pem + ``` - `sslpassword=`: Password that was used to secure the PKCS12 file. The `openssl` command listed in the previous step will ask for a password while creating the PKCS12 file, you will need to provide that same exact password here. -- `sslaccept=(strict|accept_invalid_certs)`: +- `sslaccept=(strict|accept_invalid_certs)`: - `strict`: Any missing value in the certificate will lead to an error. For Google Cloud, especially if the database doesn't have a domain name, the certificate might miss the domain/IP address, causing an error when connecting. - `accept_invalid_certs` (default): Bypass this check. Be aware of the security consequences of this setting. -To recap, in order to create a SSL connection to your database, you need: +To recap, in order to create a SSL connection to your database, you need: -- A root [CA](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc778623(v=ws.10)?redirectedfrom=MSDN) file +- A root [CA]() file - A [PKCS12](https://en.wikipedia.org/wiki/PKCS_12) client file - A [PKCS12](https://en.wikipedia.org/wiki/PKCS_12) password Your database connection URL will look similar to this: ``` -postgresql://user:password@host?sslidentity=client-identity.p12&sslpassword=mypassword&sslcert=rootca.cert +postgresql://USER:PASSWORD@HOST:PORT/DATABASE?sslidentity=client-identity.p12&sslpassword=mypassword&sslcert=rootca.cert ``` ### Connecting via sockets To connect to your PostgreSQL database via sockets, you must add a `host` field as a _query parameter_ to the connection string (instead of setting it as the `host` part of the URI). -The value of this parameter then must point to the directory that contains the socket, e.g.: -`postgresql://user:password@localhost/database?host=/var/run/postgresql/` +The value of this parameter then must point to the directory that contains the socket, e.g.: `postgresql://USER:POST@localhost/database?host=/var/run/postgresql/` + Note that `localhost` is required, the value itself is ignored and can be anything. -Learn more in this [GitHub issue](https://github.com/prisma/prisma-client-js/issues/437#issuecomment-592436707). \ No newline at end of file +> **Note**: You can find additional context in this [GitHub issue](https://github.com/prisma/prisma-client-js/issues/437#issuecomment-592436707). + +## Type mapping between PostgreSQL to Prisma schema + +The PostgreSQL connector maps the [scalar types]() from the Prisma [data model]() as follows to native column types: + +### Prisma Migrate + +| Prisma | PostgreSQL | +| ---------- | ----------- | +| `String` | `text` | +| `Boolean` | `boolean` | +| `Int` | `integer` | +| `Float` | `real` | +| `Datetime` | `timestamp` | + +### Introspection + +When introspecting a PostgreSQL database, the database types are mapped to Prisma according to the following table: + +| PostgreSQL | Prisma | Supported | +| ------------------------------------------- | ---------- | :-------: | +| `smallint` \| `int2` | `Int` | ✔️ | +| `integer` \| `int`, `int4` | `Int` | ✔️ | +| `bigint` \| `int8` | `Int` | ✔️ | +| `numeric(p,s)` \| `decimal(p,s)` | `Float` | ✔️ | +| `real` \| `float`, `float4` | `Float` | ✔️ | +| `double precision` \| `float8` | `Float` | ✔️ | +| `smallserial` \| `serial2` | `Int` | ✔️ | +| `serial` \| `serial4` | `Int` | ✔️ | +| `bigserial` \| `serial8` | `Int` | ✔️ | +| `money` | `Float` | ✔️ | +| `character(n)` \| `char(n)` | `String` | ✔️ | +| `character varying(n)` \| `varchar(n)` | `String` | ✔️ | +| `text` | `String` | ✔️ | +| `timestamp with time zone` \| `timestamptz` | `DateTime` | ✔️ | +| `date` | `DateTime` | ✔️ | +| `time without time zone` \| `time` | `DateTime` | ✔️ | +| `time with time zone` \| `timetz` | `DateTime` | ✔️ | +| `boolean` \| `bool` | `Bool` | ✔️ | +| `enum` | `Enum` | ✔️ | +| `inet` | `String` | ✔️ | +| `bit(n)` | `String` | ✔️ | +| `bit varying(n)` | `String` | ✔️ | +| `uuid` | `String` | ✔️ | +| `json` | `String` | ✔️ | +| `jsonb` | `String` | ✔️ | +| Array types | `[]` | ✔️ | +| `interval` | `String` | Not yet | +| `cidr` | `String` | Not yet | +| `macaddr` | `String` | Not yet | +| `tsvector` | `String` | Not yet | +| `tsquery` | `String` | Not yet | +| `oid` | `Int` | Not yet | +| `int4range` | `String` | Not yet | +| `int8range` | `String` | Not yet | +| `numrange` | `String` | Not yet | +| `tsrange` | `String` | Not yet | +| `tstzrange` | `String` | Not yet | +| `daterange` | `String` | Not yet | +| `xml` | n/a | Not yet | +| `bytea` | n/a | Not yet | +| `point` | n/a | Not yet | +| `line` | n/a | Not yet | +| `lseg` | n/a | Not yet | +| `box` | n/a | Not yet | +| `path` | n/a | Not yet | +| `polygon` | n/a | Not yet | +| `circle` | n/a | Not yet | +| Composite types | n/a | Not yet | +| Domain types | n/a | Not yet | + +During [introspection](), fields with types that **already have match in the Prisma schema but are not yet supported** will be added to the Prisma schema as comments, e.g. `macaddr` would be added to a model as follows: + +```prisma +model Device { + id Int @id @default(autoincrement()) + name String +// This type is currently not supported. +// mac String +} +``` + +Fields with types that **do not yet have match in the Prisma schema (and are not yet supported)** will be also be added as comments to the Prisma schema as comments using the PostgreSQL type, e.g. `macaddr` would be added to a model as follows: + +```prisma +model Device { + id Int @id @default(autoincrement()) + name String +// This type is currently not supported. +// data xml +} +``` \ No newline at end of file diff --git a/content/03-reference/02-database-connectors/02-mysql.mdx b/content/03-reference/02-database-connectors/02-mysql.mdx index 0bb0450394..102b3a5002 100644 --- a/content/03-reference/02-database-connectors/02-mysql.mdx +++ b/content/03-reference/02-database-connectors/02-mysql.mdx @@ -1,7 +1,200 @@ --- + title: 'MySQL' metaTitle: '' metaDescription: '' --- -Coming 🔜 +## Overview + +The MySQL data source connector connects Prisma to a [MySQL]() database server. + +## Example + +To connect to a MySQL database server, you need to configure a [`datasource`]() block in your [Prisma schema file](): + +```prisma +datasource mysql { + provider = "mysql" + url = env("DATABASE_URL") +} +``` + +The fields passed to the `datasource` block are: + +- `provider`: Specifies the `mysql` data source connector. +- `url`: Specifies the [connection URL](#connection-url) for the MySQL database server. In this case, an [environment variable is used]() to provide the connection URL. + +## Connection details + +### Connection URL + +Here's an overview of the components needed for a MySQL connection URL: + +![](![](https://imgur.com/NswjbsP.png) + +**Base URL and path** + +Here is an example of the structure of the _base URL_ and the _path_ using placeholder values in uppercase letters: + +``` +mysql://USER:PASSWORD@HOST:PORT/DATABASE +``` + +The following components make up the _base URL_ of your database, they are always required: + +| Name | Placeholder | Description | +| :------- | :---------- | :---------------------------------------------------------- | +| Host | `HOST` | IP address/domain of your database server, e.g. `localhost` | +| Port | `PORT` | Port on which your database server is running, e.g. `5432` | +| User | `USER` | Name of your database user, e.g. `janedoe` | +| Password | `PASSWORD` | Password for your database user | +| Database | `DATABASE` | Name of the [database]() you want to use, e.g. `mydb` | + +**Arguments** + +A connection URL can also take arguments. Here is the same example from above with placeholder values in uppercase letters for three _arguments_: + +``` +mysql://USER:PASSWORD@HOST:PORT/DATABASE?KEY1=VALUE&KEY2=VALUE&KEY3=VALUE +``` + +The following arguments can be used + +| Argument name | Required | Default | Description | +| :----------------- | :------- | ---------------------- | ------------------------------------------------------------------------------ | +| `schema` | **Yes** | `public` | Mame of the schema you want to use, e.g. `myschema` | +| `connection_limit` | No | `num_cpus * 2 + 1` | Maximum size of the [connection pool]() | +| `connect_timeout` | No | `5` | Maximum number of seconds to wait for a new connection | +| `socket_timeout` | No | `5` | Maximum number of seconds to wait until a single query terminates | +| `sslmode` | No | `prefer` | Configures whether to use TLS, possible values: `prefer`, `disable`, `require` | +| `sslcert` | No | | Path the the server certificate | +| `sslidentity` | No | | Path to the PKCS12 certificate | +| `sslpassword` | No | | Password that was used to secure the PKCS12 file | +| `sslaccept` | No | `accept_invalid_certs` | Configures whether to check for missing values in the certificate | +| `host` | No | | Points to a directory that contains a socket to be used for the connection | + +As an example, if you want to connect to a schema called `myschema`, set the connection pool size to `5` and configure a timeout for queries of `3` seconds, you can use the following arguments: + +``` +mysql://USER:PASSWORD@HOST:PORT/DATABASE?schema=myschema&connection_limit=5&socket_timeout=3 +``` + +### Configuring an SSL connection + +You can add various parameters to the connection string if your database server uses SSL. Here's an overview of the possible parameters: + +- `sslmode=(disable|prefer|require)`: + - `prefer` (default): Prefer TLS if possible, accept plain text connections. + - `disable`: Do not use TLS. + - `require`: Require TLS or fail if not possible. +- `sslcert=`: Path the the server certificate. This is the root certificate used by the database server to sign the client certificate. You need to provide this if the certificate doesn't exist in the trusted certificate store of your system. For Google Cloud this likely is `server-ca.pem`. +- `sslidentity=`: Path to the PKCS12 certificate database created from client cert and key. This is the SSL identity file in PKCS12 format which you will generate using the client key and client certificate. It combines these two files in a single file and secures them via a password (see next parameter). You can create this file using your client key and client certificate by using the following command (using `openssl`): + ``` + openssl pkcs12 -export -out client-identity.p12 -inkey client-key.pem -in client-cert.pem + ``` +- `sslpassword=`: Password that was used to secure the PKCS12 file. The `openssl` command listed in the previous step will ask for a password while creating the PKCS12 file, you will need to provide that same exact password here. +- `sslaccept=(strict|accept_invalid_certs)`: + - `strict`: Any missing value in the certificate will lead to an error. For Google Cloud, especially if the database doesn't have a domain name, the certificate might miss the domain/IP address, causing an error when connecting. + - `accept_invalid_certs` (default): Bypass this check. Be aware of the security consequences of this setting. + +To recap, in order to create a SSL connection to your database, you need: + +- A root [CA]() file +- A [PKCS12](https://en.wikipedia.org/wiki/PKCS_12) client file +- A [PKCS12](https://en.wikipedia.org/wiki/PKCS_12) password + +Your database connection URL will look similar to this: + +``` +mysql://USER:PASSWORD@HOST:PORT/DATABASE?sslidentity=client-identity.p12&sslpassword=mypassword&sslcert=rootca.cert +``` + +### Connecting via sockets + +To connect to your MySQL database via sockets, you must add a `host` field as a _query parameter_ to the connection string (instead of setting it as the `host` part of the URI). +The value of this parameter then must point to the directory that contains the socket, e.g.: `mysql://USER:POST@localhost/database?host=/var/run/mysql/` + +Note that `localhost` is required, the value itself is ignored and can be anything. + +> **Note**: You can find additional context in this [GitHub issue](https://github.com/prisma/prisma-client-js/issues/437#issuecomment-592436707). + +## Type mapping between MySQL to Prisma schema + +The MySQL connector maps the [scalar types]() from the Prisma [data model]() as follows to native column types: + +### Prisma Migrate + +| Data model | MySQL | +| -------- | --------- | +| `String` | `TEXT` | +| `Boolean` | `BOOLEAN` | +| `Int` | `INT` | +| `Float` | `FLOAT` | +| `Datetime` | `TIMESTAMP` | + +### Introspection + +When introspecting a MySQL database, the database types are mapped to Prisma according to the following table: + +| MySQL | Prisma | Supported | +| ------------------------- | ---------- | --------- | +| `smallint` | `Int` | ✔️ | +| `int` | `Int` | ✔️ | +| `bigint` | `Int` | ✔️ | +| `decimal` | `Float` | ✔️ | +| `float` | `Float` | ✔️ | +| `double` | `Float` | ✔️ | +| `bit` | `Int` | ✔️ | +| `boolean` \| `tinyint(1)` | `Boolean` | ✔️ | +| `date` | `DateTime` | ✔️ | +| `datetime` | `DateTime` | ✔️ | +| `timestamp` | `DateTime` | ✔️ | +| `time` | `DateTime` | ✔️ | +| `year` | `Int` | ✔️ | +| `char` | `String` | ✔️ | +| `varchar` | `String` | ✔️ | +| `tinytext` | `String` | ✔️ | +| `text` | `String` | ✔️ | +| `mediumtext` | `String` | ✔️ | +| `longtext` | `String` | ✔️ | +| `enum` | `Enum` | ✔️ | +| `json` | `String` | ✔️ | +| `varbinary` | `String` | Not yet | +| `tinyblob` | `String` | Not yet | +| `mediumblob` | `String` | Not yet | +| `blob` | `String` | Not yet | +| `binary` | | Not yet | +| `set` | | Not yet | +| `geometry` | | Not yet | +| `point` | | Not yet | +| `linestring` | | Not yet | +| `polygon` | | Not yet | +| `multipoint` | | Not yet | +| `multilinestring` | | Not yet | +| `multipolygon` | | Not yet | +| `geometrycollection` | | Not yet | + + + +During [introspection](), fields with types that **already have match in the Prisma schema but are not yet supported** will be added to the Prisma schema as comments, e.g. `macaddr` would be added to a model as follows: + +```prisma +model Device { + id Int @id @default(autoincrement()) + name String +// This type is currently not supported. +// mac String +} +``` + +Fields with types that **do not yet have match in the Prisma schema (and are not yet supported)** will be also be added as comments to the Prisma schema as comments using the MySQL type, e.g. `macaddr` would be added to a model as follows: + +```prisma +model Device { + id Int @id @default(autoincrement()) + name String +// This type is currently not supported. +// data xml +} +``` \ No newline at end of file diff --git a/content/03-reference/02-database-connectors/03-sqlite.mdx b/content/03-reference/02-database-connectors/03-sqlite.mdx index 38dae3a2de..28633947c5 100644 --- a/content/03-reference/02-database-connectors/03-sqlite.mdx +++ b/content/03-reference/02-database-connectors/03-sqlite.mdx @@ -4,4 +4,64 @@ metaTitle: '' metaDescription: '' --- -Coming 🔜 +## Overview + +The SQLite data source connector connects Prisma to a [SQLite](https://www.sqlite.org/) database file. These files always have the file ending `.db` (e.g.: `dev.db`). + +## Example + +To connect to a SQLite database file, you need to configure a [`datasource`]() block in your [schema file](): + +```prisma +datasource sqlite { + provider = "sqlite" + url = "file:./dev.db" +} +``` + +The fields passed to the `datasource` block are: + +- `provider`: Specifies the `sqlite` data source connector. +- `url`: Specifies the [connection string](#connection-string) for the SQLite database. The connection string always starts with the prefix `file:` and then contains a file path pointing to the SQLite database file. In this case, the file is located in the same directory and called `dev.db`. + +## Data model mapping + +The SQLite connector maps the [scalar types]() from the [data model]() to native column types as follows: + +| Data model | SQLite | +| -------- | --------- | +| `String` | `TEXT` | +| `Boolean` | `BOOLEAN` | +| `Int` | `INTEGER` | +| `Float` | `REAL` | + +## Connection details + +### Connection URL + +The connection URL of a SQLite connector points to a file on your file system. For example, the following two paths are equivalent because the `.db` iss in the same directory: + +```prisma +datasource sqlite { + provider = "sqlite" + url = "file:./dev.db" +} +``` + +is the same as: + +```prisma +datasource sqlite { + provider = "sqlite" + url = "file:dev.db" +} +``` + +You can also target files from the root or any other place in your file system: + +```prisma +datasource sqlite { + provider = "sqlite" + url = "file:/Users/janedoe/dev.db" +} +``` \ No newline at end of file diff --git a/content/03-reference/02-database-connectors/04-connection-urls.mdx b/content/03-reference/02-database-connectors/04-connection-urls.mdx index 412b22caa1..d551b8d537 100644 --- a/content/03-reference/02-database-connectors/04-connection-urls.mdx +++ b/content/03-reference/02-database-connectors/04-connection-urls.mdx @@ -31,5 +31,6 @@ dataource postgresql { The format of the connection URL depends on the _database connector_ you're using. Prisma supports the standard formats for each database. + https://www.postgresql.org/docs/current/libpq-connect.html#id-1.7.3.8.3.6 https://www.sqlite.org/c3ref/open.html \ No newline at end of file diff --git a/content/04-guides/01-database-workflows/07-data-validation/index.mdx b/content/04-guides/01-database-workflows/07-data-validation/index.mdx index d532994bde..e9a6ec135a 100644 --- a/content/04-guides/01-database-workflows/07-data-validation/index.mdx +++ b/content/04-guides/01-database-workflows/07-data-validation/index.mdx @@ -1,4 +1,4 @@ --- -title: 'Data validation' +title: 'Renaming tables and columns' metaTitle: '' --- From e5f3ac9a18d03a61caebed5447739dcda264b0d4 Mon Sep 17 00:00:00 2001 From: Nikolas Burk Date: Mon, 23 Mar 2020 20:23:06 +0100 Subject: [PATCH 7/8] continue docs --- .../04-connection-urls.mdx | 51 ++++++++++++++++--- content/05-more/01-about-the-docs.mdx | 2 +- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/content/03-reference/02-database-connectors/04-connection-urls.mdx b/content/03-reference/02-database-connectors/04-connection-urls.mdx index d551b8d537..48ac98ec52 100644 --- a/content/03-reference/02-database-connectors/04-connection-urls.mdx +++ b/content/03-reference/02-database-connectors/04-connection-urls.mdx @@ -18,19 +18,58 @@ The connection URL is provided via the `url` field of a `datasource` block in yo Make sure you have this information at hand when getting started with Prisma. If you don't have a database server running yet, you can either use a local SQLite database file (see the [Quickstart]()) or [setup a free PostgreSQL database on Heroku](https://dev.to/prisma/how-to-setup-a-free-postgresql-database-on-heroku-1dc1). -Here is an example for a local PostgreSQL database: +## Examples + +Here are examples for the connection URLs of the databases Prisma supports: + +**PostgreSQL** ```prisma -dataource postgresql { +datasource postgresql { provider = "postgresql" url = "postgresql://janedoe:mypassword@localhost:5432/mydb" } ``` -## Format +**MySQL** + +```prisma +datasource mysql { + provider = "mysql" + url = "mysql://janedoe:mypassword@localhost:3306/mydb" +} +``` + +**SQLite** + +```prisma +datasource mysql { + provider = "sqlite" + url = "file:./dev.db" +} +``` -The format of the connection URL depends on the _database connector_ you're using. Prisma supports the standard formats for each database. +Note thay you can also provide the connection URL as an environment variable like so: + +```prisma +datasource postgresql { + provider = "postgresql" + url = env("DATABASE_URL") +} +``` + +You can then either set the environment variable in your terminal or by providing a [dotenv]() file called `.env`. This will automatically be picked up by the Prisma CLI. + +**.env** + +``` +DATABASE_URL=postgresql://janedoe:mypassword@localhost:5432/mydb +``` + +## Format +The format of the connection URL depends on the _database connector_ you're using. Prisma generally supports the standard formats for each database. You can find out more about the connection URL of your database on the dedicated docs page: -https://www.postgresql.org/docs/current/libpq-connect.html#id-1.7.3.8.3.6 -https://www.sqlite.org/c3ref/open.html \ No newline at end of file +- [PostgreSQL]() +- [MySQL]() +- [SQLite]() \ No newline at end of file diff --git a/content/05-more/01-about-the-docs.mdx b/content/05-more/01-about-the-docs.mdx index fb19e4f36d..f2311ca797 100644 --- a/content/05-more/01-about-the-docs.mdx +++ b/content/05-more/01-about-the-docs.mdx @@ -14,4 +14,4 @@ Coming 🔜 ## Naming conventions for tables and columns -Table names are generally spelled in [PascalCase](). Column names in [camelCase](). \ No newline at end of file +Table names are generally spelled in [PascalCase](). Column names in [camelCase](). From d3f904ec5588b0400e3d7946b03c5817ec551851 Mon Sep 17 00:00:00 2001 From: Nikolas Burk Date: Mon, 23 Mar 2020 20:37:00 +0100 Subject: [PATCH 8/8] continue docs --- .../04-type-mappings.mdx | 101 ------------------ 1 file changed, 101 deletions(-) delete mode 100644 content/03-reference/02-database-connectors/04-type-mappings.mdx diff --git a/content/03-reference/02-database-connectors/04-type-mappings.mdx b/content/03-reference/02-database-connectors/04-type-mappings.mdx deleted file mode 100644 index 5807e513cd..0000000000 --- a/content/03-reference/02-database-connectors/04-type-mappings.mdx +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: 'Type mappings' -metaTitle: '' -metaDescription: '' ---- - -## PostgreSQL - -| Postgres Type | Prisma Type | Currently | w/o Native Types | For launch | Comment | -|---------------------------------------------------------------------------------------------------|-------------|-----------|------------------|------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| smallint \| int2 | Int | Yes | No | Yes | | -| "integer \| int, int4" | Int | Yes | No | Yes | | -| bigint \| int8 | Int | Yes | No | Yes | | -| "numeric(p,s) \| decimal(p,s)" | Float | Yes | No | Yes | Could introduce Decimal type in the future. | -| "real \| float, float4" | Float | Yes | No | Yes | | -| double precision \| float8 | Float | Yes | No | Yes | | -| smallserial \| serial2 | Int | Yes | No | Yes | Automatically creates a sequence | -| serial \| serial4 | Int | Yes | No | Yes | Automatically creates a sequence | -| bigserial \| serial8 | Int | Yes | No | Yes | Automatically creates a sequence | -| money | Float | No | Yes | Yes | "Only stores 2 decimal points, silently truncates" | -| character(n) \| char(n) | String | Yes | No | Yes | | -| character varying(n) \| varchar(n) | String | Yes | No | Yes | | -| text | String | Yes | No | Yes | | -| bytea | | No | No | No | "Most likely, our character set of choice (UTF8) is not able to express all characters possible, leading to data loss issues if people load a binary value and save it again. We should probably not convert this to String type." | -| timestamp without time zone \| timestamp | DateTime | Yes | No | Yes | Silently truncates a provided time zone | -| timestamp with time zone \| timestamptz | DateTime | Yes | No | Yes | Silently adds local time zone if not provided | -| date | DateTime | Yes | No | Yes | Silently truncates provided time component | -| time without time zone \| time | DateTime | Yes | No | Yes | Silently truncates date and time zone components | -| time with time zone \| timetz | DateTime | Yes | No | Yes | Silently truncates date component. Adds local time zone if missing | -| interval | String | No | Yes | No | Will fail if inserting a malformed string: invalid input syntax for type interval | -| boolean \| bool | Bool | Yes | No | Yes | | -| enum | Enum | Yes | No | Yes | | -| point | | No | No | No | Doesn't map cleanly to our current types. | -| line | | No | No | No | Doesn't map cleanly to our current types. | -| lseg | | No | No | No | Doesn't map cleanly to our current types. | -| box | | No | No | No | Doesn't map cleanly to our current types. | -| path | | No | No | No | Doesn't map cleanly to our current types. | -| polygon | | No | No | No | Doesn't map cleanly to our current types. | -| circle | | No | No | No | Doesn't map cleanly to our current types. | -| cidr | String | No | Yes | No | input and output is string. will error on malformed data. | -| inet | String | No | Yes | Yes | input and output is string. will error on malformed data. subnet component is silently truncated | -| macaddr | String | No | Yes | No | input and output is string. will error on malformed data. | -| bit(n) | String | No | Yes | Yes | input and output is string (e.g. 1011). will error on malformed data. Will error if the string is not the exact length n. | -| bit varying(n) | String | No | Yes | Yes | input and output is string. will error on malformed data. Will error if string is longer than n. | -| tsvector | String | No | Yes | No | "Accepts a string. Each word is turned into a list item in quotes. The following statements are equivalent. quoted: UPDATE ""public"".""types"" SET ""tsvector""='''a'' ''dump'' ''dumps'' ''fox'' ''in'' ''the''' WHERE ""id""=1 RETURNING ""tsvector""; unquoted: UPDATE ""public"".""types"" SET ""tsvector""='a fox dumps in the dump' WHERE ""id""=1 RETURNING ""tsvector""; and both result in the stored value being 'a' 'dump' 'dumps' 'fox' 'in' 'the'. For this reason we need to support double quoting by turning 'a' 'dump' 'dumps' 'fox' 'in' 'the' into '''a'' ''dump'' ''dumps'' ''fox'' ''in'' ''the''' during data insertion." | -| tsquery | String | No | Yes | No | "Inserted data must be double quoted. works: SET ""tsquery""='''foxy cat''' doesn't work: SET ""tsquery""='foxy cat'. The returned value is also quoted, so we can probably make this work without the Query Engine having specific knowledge of tsquery" | -| uuid | String | No | Yes | Yes | String in and out. Accepts different formatting and always returns a standard format. Will error if input is malformed | -| xml | | No | No | No | "Postgres requires wrapping syntax on input, so we cannot treat it as string: 'bar'::xml. Also, does not support comparison." | -| json | String | No | Yes | Yes | "text in and out. Will complain if malformed. Example: {""a"": 3}" | -| jsonb | String | No | Yes | Yes | "text in and out. Will complain if malformed. Example: {""a"": 3}" | -| Array types | | Yes | No | Yes | We simply treat this as a https://github.com/prisma/prisma2/blob/master/docs/data-modeling.md#type-modifiers for any of our scalar types. This is implemented and works | -| Composite types | | No | No | No | We don't support this | -| "oid \| regproc, regprocedure, regoper, regoperator, regclass, regtype, regconfig, regdictionary" | Int | No | Yes | No | "Integer in and out. Will return OID out of range if too big, and overflow if negative." | -| int4range | String | No | Yes | No | "String in and out. Complains if malformed. Example: [2,3)" | -| int8range | String | No | Yes | No | String in and out. Complains if malformed. | -| numrange | String | No | Yes | No | String in and out. Complains if malformed. | -| tsrange | String | No | Yes | No | String in and out. Complains if malformed. | -| tstzrange | String | No | Yes | No | String in and out. Complains if malformed. | -| daterange | String | No | Yes | No | String in and out. Complains if malformed. | -| Domain types | | No | No | No | We don't support this | - - -## MySQL - -| MySQL Type | Prisma Type | Currently | w/o Native Types | For launch | Comment | -|----------------------|-------------|-----------|------------------|------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| smallint | Int | Yes | No | Yes | | -| int | Int | Yes | No | Yes | | -| bigint | Int | Yes | No | Yes | Can we hold the full range? | -| decimal | Float | Yes | No | Yes | Can we hold the full range of the biggest possible range? Do we need a dedicated Decimal value? | -| float | Float | Yes | No | Yes | | -| double | Float | Yes | No | Yes | Can we hold the full range? | -| bit | Int | No | Yes | Yes | "MySQL performs normal Int ↔ bit conversion: 1 → 1, 2 → 10, 3 → 11 ..." | -| boolean / tinyint(1) | Bool | Yes | No | Yes | | -| date | DateTime | No | Yes | Yes | Rely on MySQL conversion | -| datetime | DateTime | Yes | Yes | Yes | | -| timestamp | DateTime | No | Yes | Yes | https://stackoverflow.com/questions/31761047/what-difference-between-the-date-time-datetime-and-timestamp-types/56138746 datetime and timestamp takes the same format. They have different ranges and treat time zones differently. | -| time | DateTime | No | Yes | Yes | MySQL simply strips the date component. When reading the data we will need to be able to turn it into a DateTime either in QE or Client. | -| year | Int | No | Yes | Yes | MySQL will return error if out of range (1901 to 2155) Funky conversion rules: https://dev.mysql.com/doc/refman/8.0/en/year.html | -| char | String | Yes | No | Yes | MySQL will silently truncate or return error if inserting long string | -| varchar | String | Yes | No | Yes | MySQL will silently truncate or return error if inserting long string | -| tinytext | String | Yes | No | Yes | MySQL will silently truncate or return error if inserting long string | -| text | String | Yes | No | Yes | MySQL will silently truncate or return error if inserting long string | -| mediumtext | String | Yes | No | Yes | MySQL will silently truncate or return error if inserting long string | -| longtext | String | Yes | No | Yes | MySQL will silently truncate or return error if inserting long string | -| binary | | No | No | No | "Conversion might behave in unexpected ways for the user: http://www.ovaistariq.net/632/understanding-mysql-binary-and-non-binary-string-data-types/#.XlWQtBNKjUI Most likely, our character set of choice (UTF8) is not able to express all characters possible, leading to data loss issues if people load a binary value and save it again. We should probably not convert this to String type. " | -| varbinary | String | No | No | No | Conversion might behave in unexpected ways for the user: http://www.ovaistariq.net/632/understanding-mysql-binary-and-non-binary-string-data-types/#.XlWQtBNKjUI | -| tinyblob | String | No | No | No | Conversion might behave in unexpected ways for the user: http://www.ovaistariq.net/632/understanding-mysql-binary-and-non-binary-string-data-types/#.XlWQtBNKjUI | -| mediumblob | String | No | No | No | Conversion might behave in unexpected ways for the user: http://www.ovaistariq.net/632/understanding-mysql-binary-and-non-binary-string-data-types/#.XlWQtBNKjUI | -| blob | String | No | No | No | Conversion might behave in unexpected ways for the user: http://www.ovaistariq.net/632/understanding-mysql-binary-and-non-binary-string-data-types/#.XlWQtBNKjUI | -| enum | Enum | Yes | No | Yes | | -| set | | No | No | No | Doesn't map cleanly to our current types. https://dev.mysql.com/doc/refman/8.0/en/set.html | -| geometry | | No | No | No | Doesn't map cleanly to our current types. | -| point | | No | No | No | Doesn't map cleanly to our current types. | -| linestring | | No | No | No | Doesn't map cleanly to our current types. | -| polygon | | No | No | No | Doesn't map cleanly to our current types. | -| multipoint | | No | No | No | Doesn't map cleanly to our current types. | -| multilinestring | | No | No | No | Doesn't map cleanly to our current types. | -| multipolygon | | No | No | No | Doesn't map cleanly to our current types. | -| geometrycollection | | No | No | No | Doesn't map cleanly to our current types. | -| json | String | Yes | No | Yes | https://github.com/prisma/prisma2-private/issues/22 |