PostgreSQL
PostgreSQL 資料來源聯結器將 Prisma ORM 連線到 PostgreSQL 資料庫伺服器。
預設情況下,PostgreSQL 聯結器包含一個負責連線到資料庫的資料庫驅動。你可以使用驅動介面卡(預覽)透過 Prisma Client 使用 JavaScript 資料庫驅動連線到資料庫。
昨天就需要 Postgres 例項?
透過 Prisma Postgres,你只需點選三下即可在裸機上執行資料庫。連線池、查詢快取和自動備份均包含在內。立即開始。
想更快地開始使用 Prisma Postgres 嗎?只需在終端中執行 npx prisma init --db。🚀
示例
要連線到 PostgreSQL 資料庫伺服器,你需要在 Prisma schema 中配置一個 datasource 塊
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
傳遞給 datasource 塊的欄位有:
使用 node-postgres 驅動
自 v5.4.0 起,你可以將 Prisma ORM 與 JavaScript 生態系統中的資料庫驅動一起使用(而不是使用 Prisma ORM 的內建驅動)。你可以透過使用驅動介面卡來實現這一點。
對於 PostgreSQL,node-postgres (pg) 是 JavaScript 生態系統中最受歡迎的驅動之一。它可以與任何透過 TCP 訪問的 PostgreSQL 資料庫一起使用。
本節解釋如何將其與 Prisma ORM 和 @prisma/adapter-pg 驅動介面卡一起使用。
1. 啟用 driverAdapters 預覽功能標誌
由於驅動介面卡目前處於預覽階段,你需要在 Prisma schema 的 datasource 塊上啟用其功能標誌
generator client {
provider = "prisma-client-js"
previewFeatures = ["driverAdapters"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
將功能標誌新增到 schema 後,重新生成 Prisma Client
npx prisma generate
2. 安裝依賴
接下來,安裝 Prisma ORM 的 pg 驅動介面卡
npm install @prisma/adapter-pg
3. 使用驅動介面卡例項化 Prisma Client
最後,當你例項化 Prisma Client 時,你需要將 Prisma ORM 驅動介面卡的一個例項傳遞給 PrismaClient 建構函式
import { PrismaPg } from '@prisma/adapter-pg'
import { PrismaClient } from '@prisma/client'
const connectionString = `${process.env.DATABASE_URL}`
const adapter = new PrismaPg({ connectionString });
const prisma = new PrismaClient({ adapter });
請注意,此程式碼要求將 DATABASE_URL 環境變數設定為 PostgreSQL 連線字串。你可以在下面瞭解更多關於連線字串的資訊。
注意事項
指定 PostgreSQL Schema
你可以透過在例項化 PrismaPg 時傳入 schema 選項來指定一個 PostgreSQL schema
const adapter = new PrismaPg(
{ connectionString },
{ schema: 'myPostgresSchema' }
)
連線詳情
連線 URL
Prisma ORM 遵循 PostgreSQL 官方指南 中指定的連線 URL 格式,但並非支援所有引數,幷包含 schema 等附加引數。以下是 PostgreSQL 連線 URL 所需元件的概述:

基礎 URL 和路徑
以下是使用大寫佔位符值的基礎 URL和路徑的結構示例
postgresql://USER:PASSWORD@HOST:PORT/DATABASE
以下元件構成資料庫的基礎 URL,它們始終是必需的:
| 名稱 | 佔位符 | 描述 |
|---|---|---|
| 主機 | HOST | 資料庫伺服器的 IP 地址/域名,例如 localhost |
| 埠 | PORT | 資料庫伺服器執行的埠,例如 5432 |
| 使用者 | USER | 資料庫使用者名稱稱,例如 janedoe |
| 密碼 | PASSWORD | 資料庫使用者的密碼 |
| 資料庫 | DATABASE | 要使用的資料庫名稱,例如 mydb |
你必須對特殊字元進行百分比編碼。
引數
連線 URL 也可以帶引數。以下是上面相同的示例,其中包含三個引數的大寫佔位符值
postgresql://USER:PASSWORD@HOST:PORT/DATABASE?KEY1=VALUE&KEY2=VALUE&KEY3=VALUE
可以使用以下引數:
| 引數名稱 | 必填 | 預設值 | 描述 |
|---|---|---|---|
schema | 是 | public | 要使用的schema的名稱,例如 myschema |
connection_limit | 否 | num_cpus * 2 + 1 | 連線池的最大大小 |
connect_timeout | 否 | 5 | 等待新連線開啟的最大秒數,0表示無超時 |
pool_timeout | 否 | 10 | 等待從連線池中獲取新連線的最大秒數,0表示無超時 |
sslmode | 否 | prefer | 配置是否使用 TLS。可能的值:prefer, disable, require |
sslcert | 否 | 伺服器證書路徑。證書路徑相對於./prisma folder解析 | |
sslrootcert | 否 | 根證書路徑。證書路徑相對於./prisma folder解析 | |
sslidentity | 否 | PKCS12 證書的路徑 | |
sslpassword | 否 | 用於保護 PKCS12 檔案的密碼 | |
sslaccept | 否 | accept_invalid_certs | 配置是否檢查證書中缺少的值。可能的值:accept_invalid_certs, strict |
host | 否 | 指向包含用於連線的 socket 的目錄 | |
socket_timeout | 否 | 等待單個查詢終止的最大秒數 | |
pgbouncer | 否 | false | 配置引擎以啟用 PgBouncer 相容模式 |
statement_cache_size | 否 | 100 | 自 2.1.0 起:指定每個連線快取的預處理語句數量 |
application_name | 否 | 自 3.3.0 起:指定 application_name 配置引數的值 | |
channel_binding | 否 | prefer | 自 4.8.0 起:指定 channel_binding 配置引數的值 |
options | 否 | 自 3.8.0 起:指定連線開始時傳送到伺服器的命令列選項 |
例如,如果你想連線到一個名為 myschema 的 schema,將連線池大小設定為 5,併為查詢配置 3 秒的超時。你可以使用以下引數:
postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=myschema&connection_limit=5&socket_timeout=3
配置 SSL 連線
如果你的資料庫伺服器使用 SSL,你可以向連線 URL 新增各種引數。以下是可能引數的概述:
sslmode=(disable|prefer|require):prefer(預設):如果可能,首選 TLS,接受純文字連線。disable:不使用 TLS。require:要求 TLS,如果不可能則失敗。
sslcert=<PATH>:伺服器證書路徑。這是資料庫伺服器用於簽署客戶端證書的根證書。如果證書不存在於系統的受信任證書儲存中,你需要提供此項。對於 Google Cloud,這很可能是server-ca.pem。證書路徑相對於./prisma folder解析sslidentity=<PATH>:客戶端證書和金鑰建立的 PKCS12 證書資料庫路徑。這是 PKCS12 格式的 SSL 身份檔案,你將使用客戶端金鑰和客戶端證書生成它。它將這兩個檔案合併為一個檔案,並透過密碼保護它們(參見下一個引數)。你可以使用以下命令(使用openssl)透過客戶端金鑰和客戶端證書建立此檔案:openssl pkcs12 -export -out client-identity.p12 -inkey client-key.pem -in client-cert.pemsslpassword=<PASSWORD>:用於保護 PKCS12 檔案的密碼。上一步中列出的openssl命令在建立 PKCS12 檔案時會要求輸入密碼,你需要在此處提供完全相同的密碼。sslaccept=(strict|accept_invalid_certs):strict:證書中任何缺失的值都將導致錯誤。對於 Google Cloud,特別是當資料庫沒有域名時,證書可能缺少域名/IP 地址,導致連線時出錯。accept_invalid_certs(預設):繞過此檢查。請注意此設定的安全後果。
你的資料庫連線 URL 將類似於這樣:
postgresql://USER:PASSWORD@HOST:PORT/DATABASE?sslidentity=client-identity.p12&sslpassword=mypassword&sslcert=rootca.cert
透過 sockets 連線
要透過 sockets 連線到 PostgreSQL 資料庫,你必須在連線 URL 中新增一個 host 欄位作為查詢引數(而不是將其設定為 URI 的 host 部分)。此引數的值必須指向包含 socket 的目錄,例如:postgresql://USER:PASSWORD@localhost/database?host=/var/run/postgresql/
請注意,localhost 是必需的,其值本身被忽略,可以是任何值。
注意:你可以在此GitHub issue中找到更多上下文。
PostgreSQL 與 Prisma schema 之間的型別對映
這兩張表顯示了 PostgreSQL 和 Prisma schema 之間的型別對映。首先是Prisma ORM 標量型別如何轉換為 PostgreSQL 資料庫列型別,然後是PostgreSQL 資料庫列型別如何與 Prisma ORM 標量型別和原生型別相關聯。
或者,請參閱Prisma schema 參考,瞭解按 Prisma 型別組織的型別對映。
Prisma ORM 標量型別與 PostgreSQL 資料庫列型別之間的對映
PostgreSQL 聯結器將 Prisma ORM 資料模型中的標量型別對映到資料庫列型別如下:
| Prisma ORM | PostgreSQL |
|---|---|
String | text |
Boolean | boolean |
Int | integer |
BigInt | bigint |
Float | double precision |
Decimal | decimal(65,30) |
DateTime | timestamp(3) |
Json | jsonb |
Bytes | bytea |
PostgreSQL 資料庫列型別與 Prisma ORM 標量型別和原生型別之間的對映
- 當內省 PostgreSQL 資料庫時,資料庫型別會根據下表對映到 Prisma ORM 型別。
- 當建立遷移或原型化 schema 時,該表也會反向使用。
| PostgreSQL (型別 | 別名) | 支援 | Prisma ORM | 原生資料庫型別屬性 | 備註 |
|---|---|---|---|---|
bigint | int8 | ✔️ | BigInt | @db.BigInt* | *BigInt的預設對映 - 未向 schema 新增型別屬性。 |
boolean | bool | ✔️ | Bool | @db.Boolean* | *Bool的預設對映 - 未向 schema 新增型別屬性。 |
timestamp with time zone | timestamptz | ✔️ | DateTime | @db.Timestamptz(x) | |
time without time zone | time | ✔️ | DateTime | @db.Time(x) | |
time with time zone | timetz | ✔️ | DateTime | @db.Timetz(x) | |
numeric(p,s) | decimal(p,s) | ✔️ | Decimal | @db.Decimal(x, y) | |
real | float, float4 | ✔️ | Float | @db.Real | |
double precision | float8 | ✔️ | Float | @db.DoublePrecision* | *Float的預設對映 - 未向 schema 新增型別屬性。 |
smallint | int2 | ✔️ | Int | @db.SmallInt | |
integer | int, int4 | ✔️ | Int | @db.Int* | *Int的預設對映 - 未向 schema 新增型別屬性。 |
smallserial | serial2 | ✔️ | Int | @db.SmallInt @default(autoincrement()) | |
serial | serial4 | ✔️ | Int | @db.Int @default(autoincrement()) | |
bigserial | serial8 | ✔️ | Int | @db.BigInt @default(autoincrement()) | |
character(n) | char(n) | ✔️ | String | @db.Char(x) | |
character varying(n) | varchar(n) | ✔️ | String | @db.VarChar(x) | |
money | ✔️ | Decimal | @db.Money | |
text | ✔️ | String | @db.Text* | *String的預設對映 - 未向 schema 新增型別屬性。 |
timestamp | ✔️ | DateTime | @db.TimeStamp* | *DateTime的預設對映 - 未向 schema 新增型別屬性。 |
date | ✔️ | DateTime | @db.Date | |
enum | ✔️ | Enum | 不適用 | |
inet | ✔️ | String | @db.Inet | |
bit(n) | ✔️ | String | @Bit(x) | |
bit varying(n) | ✔️ | String | @VarBit | |
oid | ✔️ | Int | @db.Oid | |
uuid | ✔️ | String | @db.Uuid | |
json | ✔️ | Json | @db.Json | |
jsonb | ✔️ | Json | @db.JsonB* | *Json的預設對映 - 未向 schema 新增型別屬性。 |
bytea | ✔️ | Bytes | @db.ByteA* | *Bytes的預設對映 - 未向 schema 新增型別屬性。 |
xml | ✔️ | String | @db.Xml | |
| 陣列型別 | ✔️ | [] | ||
citext | ✔️* | String | @db.Citext | * 僅當啟用 Citext 擴充套件時可用。 |
interval | 尚未 | 不支援 | ||
cidr | 尚未 | 不支援 | ||
macaddr | 尚未 | 不支援 | ||
tsvector | 尚未 | 不支援 | ||
tsquery | 尚未 | 不支援 | ||
int4range | 尚未 | 不支援 | ||
int8range | 尚未 | 不支援 | ||
numrange | 尚未 | 不支援 | ||
tsrange | 尚未 | 不支援 | ||
tstzrange | 尚未 | 不支援 | ||
daterange | 尚未 | 不支援 | ||
point | 尚未 | 不支援 | ||
line | 尚未 | 不支援 | ||
lseg | 尚未 | 不支援 | ||
box | 尚未 | 不支援 | ||
path | 尚未 | 不支援 | ||
polygon | 尚未 | 不支援 | ||
circle | 尚未 | 不支援 | ||
| 複合型別 | 尚未 | 不適用 | ||
| 域型別 | 尚未 | 不適用 |
內省將尚不支援的原生資料庫型別新增為Unsupported欄位
model Device {
id Int @id @default(autoincrement())
name String
data Unsupported("circle")
}
預處理語句快取
預處理語句是一種可以用於最佳化效能的特性。預處理語句只解析、編譯和最佳化一次,然後可以直接執行多次,而無需再次解析查詢的開銷。
透過快取預處理語句,Prisma Client 的查詢引擎不會重複編譯相同的查詢,從而減少資料庫 CPU 使用率和查詢延遲。
例如,以下是 Prisma Client 生成的兩個不同查詢的 SQL:
SELECT * FROM user WHERE name = "John";
SELECT * FROM user WHERE name = "Brenda";
引數化後,這兩個查詢將是相同的,第二個查詢可以跳過準備步驟,從而節省資料庫 CPU 和一次額外的資料庫往返。引數化後的查詢:
SELECT * FROM user WHERE name = $1
Prisma Client 維護的每個資料庫連線都有一個獨立的快取,用於儲存預處理語句。此快取的大小可以透過連線字串中的 statement_cache_size 引數進行調整。預設情況下,Prisma Client 每個連線快取 100 個語句。
由於 pgBouncer 的特性,如果 pgbouncer 引數設定為 true,該連線的預處理語句快取會自動停用。