前提条件:安装好Docker Desktop、NodeJS以及具备一定的TypeScript基础
本教程实验环境为Windows 11、NodeJS-20.15.0、Docker-27.2.0
本地部署的数据库同样可以实现,确保数据库可以成功连接即可
1. Docker部署PostgreSQL
1.1 首先创建一个空文件夹
D:\> mkdir postgresql D:\> cd postgresql
|
1.2 配置Docker Compose
Docker Compose
简化了对整个应用程序堆栈的控制,使得在一个易于理解的 YAML 配置文件中轻松管理服务、网络和数据卷。 接下来我们创建配置文件来对它进行配置。
在上面创建好的空文件夹中创建配置文件docker-compose.yml
,并编辑:
services: postgres_db: image: postgres:15.7 container_name: docker_postgres environment: POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres POSTGRES_USER: postgres ports: - "5432:5432" volumes: - data:/var/lib/postgresql/data - log:/var/log/postgresql
volumes: data: log:
|
对配置文件中属性的一些注解:
image
: 指定了要使用的 Docker 镜像及其版本。在这里,我们使用了官方的 PostgreSQL 15.7 版本镜像。为了确保系统的稳定性和兼容性,推荐使用 PostgreSQL 官方镜像的一个稳定版本而不是最新版latest
。如果没有写版本,将会默认使用最新版本latest
。
contain_name
: 容器名称。
environment
: 环境变量,可以是数据库的用户名、数据库类型和密码。
ports
: 端口。
volumes
: 数据持久化卷。这个可以保证容器被删除的情况下,数据卷中的数据不会丢失。如果不需要可以把日志数据卷去掉。很多不被使用的数据卷可能会占用很大的存储空间。
1.3 部署和验证
接下来启动Docker Compose
,它会按照配置文件来配置容器,我们已经配置了数据库镜像,所以启动后它会自动拉取Postgresql
数据库镜像并部署运行:
D:\postgresql> docker compose up -d
|
如果没有刚才创建的docker-compose.yml
配置文件,将会报错:
D:\postgresql> docker compose up -d no configuration file provided: not found
|
部署成功显示如下:
[+] Running 1/1 [+] Running 1/2tgresql_default Created 0.1s [+] Running 1/2tgresql_default Created 0.1s [+] Running 1/2tgresql_default Created 0.1s [+] Running 1/2tgresql_default Created 0.1s [+] Running 1/2tgresql_default Created 0.1s [+] Running 2/2tgresql_default Created 0.1s ✔ Network postgresql_default Created 0.1s - Container docker_postgres Starting 0.6s ✔ Container docker_postgres Started 0.7s
|
这里我已经运行过相同指令,所以输出可能会有所不同,初次运行可能的成功结果如下:
[+] Running 15/15 ✔ postgres_db Pulled 61.9s ✔ 09f376ebb190 Pull complete 8.9s ✔ 119215dfb3e3 Pull complete 2.0s ✔ 94fccb772ad3 Pull complete 10.7s ✔ 0fc3acb16548 Pull complete 8.6s ✔ d7dba7d03fe8 Pull complete 13.1s ✔ 898ae395a1ca Pull complete 12.6s ✔ 088e651df7e9 Pull complete 12.4s ✔ ed155773e5e0 Pull complete 14.2s ✔ 52df7d12fb73 Pull complete 33.4s ✔ bab1ecc22dc9 Pull complete 15.2s ✔ 1655a257a5b5 Pull complete 16.0s ✔ 978f02dfc247 Pull complete 18.0s ✔ d715d7d9aee0 Pull complete 17.8s ✔ b2e9251b2f8d Pull complete 19.8s [+] Running 3/3 ✔ Volume "postgresql_log" Created 0.0s ✔ Volume "postgresql_data" Created 0.0s ✔ Container docker_postgres Started 0.9s
|
接着,验证一下数据库是否在运行:
D:\postgresql>docker compose ps NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS docker_postgres postgres:15.7 "docker-entrypoint.s…" postgres_db 4 minutes ago Up 4 minutes 0.0.0.0:5432->5432/tcp
|
可以看到,数据库已成功部署。
2. Prisma远程操作数据库
2.1 环境配置
初始化一个 TypeScript 项目,并将 Prisma CLI 作为开发依赖项添加到其中。
D:\postgresql>npm init -y Wrote to D:\postgresql\package.json: { "name": "postgresql", "version": "1.0.0", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "description": "" }
|
D:\postgresql>npm install prisma typescript ts-node @types/node --save-dev added 26 packages in 9s
|
这将创建一个包含 TypeScript 应用程序的初始设置的 package.json
。接着初始化TypeScirpt:
D:\postgresql> npmx tsc --init
|
我们可以尝试调用prisma
:
D:\postgresql> npx prisma
|
然后,初始化prisma
,并生成环境配置文件.env
:
D:\postgresql> npx prisma init
|
.env
中存放数据库的远程链接等内容。PostgreSQL的远程链接地址一般如下:
DATABASE_URL="postgresql://username:password@localhost:5432/sqlname"
|
记得将username
password
以及 sqlname
替换成刚才创建docker
中的配置文件中的信息docker-compose.yml
.
例如我的.env
文件内容为:(参考我的docker-compose.yml
)
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres"
|
2.2 创建数据库表
prisma
中数据库表用model
表示,它提供了多种属性类型等,在schema.prisma
中写入两张表,关于数据库表的属性的设计可以参考官网:
generator client { provider = "prisma-client-js" }
datasource db { provider = "postgresql" url = env("DATABASE_URL") }
model Profile { id Int @id @default(autoincrement()) bio String user User @relation(fields: [userId], references: [id]) userId Int @unique }
model User { id Int @id @default(autoincrement()) name String age Int profile Profile? }
|
在进行数据库映射:
D:\postgresql> npx prisma migrate dev --name init
|
这样操作之后,远程对数据库的更改就可以同步到我们的数据库镜像中。
2.3 增删改查 (CURD)
创建一个index.ts
文件,用来通过prisma
操作数据库:
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
async function main() { const user = await prisma.user.findMany(); console.log(user); } main() .then(async () => { await prisma.$disconnect() }) .catch(async (e) => { console.error(e) await prisma.$disconnect() process.exit(1) })
|
根据我们之前创建的两张表User
和Profile
,我们上面的操作是对User
进行了查询操作。[table].findMany()
方法是对表格的查询,请注意,根据prisma
规范,表格的名称在创建是首字母应该大写,但是对表格进行操作时,表格的名称应全部改成小写,所以在上面的代码中,prisma.user.findMany()
中的表格名称user
是小写的。
运行index.ts
文件:
D:\postgresql> npx ts-node index.ts
|
如果正确执行,那么会打印出一个空数组,显而易见,由于表格新创建,所以里面没有数据内容。
下面我们来写入数据库,修改index.ts
:
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
async function addUser(){ await prisma.user.create({ data:{ name:"hi", age: 18, profile: { create: { bio: "I am a software developer" } } } }) const profile = await prisma.profile.findMany() console.log(profile) }
addUser() .then(async () => { await prisma.$disconnect() }) .catch(async (e) => { console.error(e) await prisma.$disconnect() process.exit(1) })
|
在上面的代码中,我们向user
写入了一个名字叫hi
、年龄为18的人,并通过绑定同时写入了profile
表格的一项bio
属性。
再次执行index.ts
,注意,我将prisma.user.findmany()
中的user
改成了profile
,所以我这次查询输出的是Profile
表格中的内容,最后的输出为:
[ { id: 1, bio: 'I am a software developer', userId: 1 }, { id: 2, bio: 'I am a software developer', userId: 2 }, { id: 3, bio: 'I am a software developer', userId: 3 }, { id: 4, bio: 'I am a software developer', userId: 4 } ]
|
可以看到确实向表格中插入的四条数据。
最后我们尝试来更新表格内容,更新的方法为update()
,语法与上述查询和插入一样,修改main
函数:
async function main() { const profile = await prisma.profile.update({ where: { id: 1 }, data: { bio: 'I am a super satr!!!' }, }) console.log(profile) }
|
我对Profile
表格使用了更新方法,在id
属性为1的位置,将bio
属性值修改成了”I am a super satr!!!”,再次运行index.ts
,最后的输出为:
[ { id: 1, bio: 'I am a super satr!!!', userId: 1 }, { id: 2, bio: 'I am a software developer', userId: 2 }, { id: 3, bio: 'I am a software developer', userId: 3 }, { id: 4, bio: 'I am a software developer', userId: 4 } ]
|
可以看到,数据已经成功更新到数据库中。