将Prisma连接到已具有数据库表/或包含某些数据的现有数据库时,从头开始手动编写数据模型同时确保它与现有数据的结构相匹配可能会非常繁琐。

要自动执行此过程,你可以使用Prisma CLI中的[prisma introspect]命令,根据现有数据的实际结构生成[datamodel]

生成的SDL可作为Prisma service的基础,但你可以根据需要轻松进行修改。一些常见的修改包括从GraphQL API隐藏表或将列赋予其他名称。

Postgres使用以下模型在内部组织数据库:

重要:当Introspecting Postgres数据库时,你实际上是根据图示的模型Introspecting schema而不是database!

有两种方法可以使用CLI来Introspecting Postgres:

  • 使用交互式prisma init向导
  • 使用专用的prisma introspect命令

在这两种情况下,你都需要为正在运行的Postgres数据库提供连接配置。这包括以下内容:

  • Host:Postgres数据库的主机,例如localhost
  • Port:Postgres数据库监听的端口,例如5432
  • User & Password:Postgres数据库的用户名和密码。
  • Name of existing database :Postgres database的名称(根据上面所示的模型)。
  • Use SSL (Yes/No):如果数据库连接使用SSL,则需要选择"是",否则选择"否"。
  • Name of existing schema :Postgres schema的名称(根据上面所示的模型),例如: public

在交互式prisma init流程中,你可以选择使用数据连接到现有数据库。 CLI将询问数据库连接详细信息(如上所述)并验证它是否可以建立成功的连接。

如果连接详细信息有效,CLI将introspect数据库并显示摘要。

prisma init终止时,CLI已为你创建了以下文件,你现在可以使用这些文件deploy一个新的Prisma service:

  • datamodel.prisma:包含基于现有数据库生成的数据模型(在SDL中)。
  • docker-compose.yml:包含Prisma service器配置的Docker Compose文件,包括有关如何连接数据库的详细信息
  • prisma.yml:服务的根配置文件

为了能够使用GraphQL查询Postgres数据库,你现在需要deploy服务并打开GraphQL Playground:


prisma deploy
prisma playground

prisma introspect的工作方式与prisma init向导类似,因为你需要提供数据库连接信息。

prisma init向导生成一个完整的service配置prisma introspect只生成datamodel文件:

  • datamodel-[TIMESTAMP].graghpql:时间戳组件允许你在不覆盖现有数据模型的情况下对现有Prisma service使用introspect命令。

在使用生成的数据模型部署服务之前,应确保Docker Compose文件中指定Prisma service器配置的migrations属性(PRISMA_CONFIG`环境变量)设置为"false":


PRISMA_CONFIG: |
  port: 4466
  databases:
    default:
      connector: postgres
      migrations: false # 确保这里为 false
      host: localhost
      port: 5432
      user: postgres
      password: postgres
      database: postgres
      schema: public

migrations设置为false可确保Prisma仅基于数据模型更新服务器的GraphQL API,但它不会执行基础Postgres数据库的合并和初始化。

根据你在SQL数据库中对表之间的关系建模的方法,生成的数据模型中的关系可能看起来不同。 以下是Prisma如何解释SQL中指定的关系的概述:

SQL中的关系由Prisma(SDL)生成的关系
内联关系列一对多
关系表多对多
带有额外列的关系表用于表达关系的专用类型

表示SQL数据库中关系的常用方法是通过foreign key约束:


CREATE TABLE product (
  id           serial PRIMARY KEY UNIQUE
, description  text NOT NULL
);
CREATE TABLE bill (
  id         serial PRIMARY KEY UNIQUE
, notes      text NOT NULL
, product_id int REFERENCES product (id) ON UPDATE CASCADE
);

在这种情况下,bill使用外键来引用product表的id,从而在两个表之间创建一个relation。 基于此表结构,Prisma生成两个SDL模型,ProductBill,具有双向关系(通过productbills字段):


type Product @pgTable(name: "product") {
  description: String!
  id: Int! @unique
  bills: [Bill!]!
}
type Bill @pgTable(name: "bill") {
  notes: String!
  id: Int! @unique
  product: Product @pgRelation(column: "product_id")
}

以下是Prisma如何为生成的字段生成名称:

  • type Product    - description:Stringproduct表中的description列命名    - id:Int!product表的id列命名    - bills:[Bill!]!bill表的复数版本命名
  • type Bill    - notes:Stringbill表上的notes列命名    - id:Int!bill表上的id列命名    - product:Productbill表上的product_id列命名; Prisma剥离了这些外键字段的后缀:_ idIDId

另一种在SQL数据库中表示关系的常用方法是通过专用的relation table来"连接"两个相关的表:


CREATE TABLE product (
  id         serial PRIMARY KEY UNIQUE
, product    text NOT NULL
);
CREATE TABLE bill (
  id       serial PRIMARY KEY UNIQUE
, bill     text NOT NULL
);
CREATE TABLE bill_product (
  bill_id    int REFERENCES bill (id) ON UPDATE CASCADE ON DELETE CASCADE
, product_id int REFERENCES product (id) ON UPDATE CASCADE
);

在这种情况下,关系表称为bill_product,简单地......只包含两列,它们都是billproduct表的id列的外键。

有时,使用关于关系本身的元信息来丰富关系表是有帮助的:


CREATE TABLE product (
  id         serial PRIMARY KEY UNIQUE
, product    text NOT NULL
);
CREATE TABLE bill (
  id       serial PRIMARY KEY UNIQUE
, bill     text NOT NULL
);
CREATE TABLE bill_product (
  bill_id    int REFERENCES bill (id) ON UPDATE CASCADE ON DELETE CASCADE
, product_id int REFERENCES product (id) ON UPDATE CASCADE
, some_other_column text NOT NULL
);

如果关系表包含此类额外信息,则Prisma会将关系表视为dedicated type:


type Bill @pgTable(name: "bill") {
  bill: String!
  id: Int! @unique
  bill_products: [Bill_product]
}
type Bill_product @pgTable(name: "bill_product") {
  bill: Bill @pgRelation(column: "bill_id")
  product: Product @pgRelation(column: "product_id")
  some_other_column: String!
}
type Product @pgTable(name: "product") {
  id: Int! @unique
  product: String!
  bill_products: [Bill_product]
}

这样,你可以充分灵活地使用常规查询和嵌套Mutation来设置和读取额外的列。

MonogDB使用以下模型在内部组织数据:

有两种方法可以使用CLI来解析MongoDB数据库:

  • 使用交互式prisma init向导
  • 使用专用的prisma introspect命令

在这两种情况下,您都需要为正在运行的MongoDB实例提供connection details。 这包括以下内容:

在交互式prisma init流程中,您可以选择使用数据连接到现有数据库。 CLI将询问数据库连接详细信息(如上所述)并验证它是否可以建立成功连接。

如果连接详细信息有效,CLI将自省数据库并显示摘要。

prisma init终止时,CLI为您创建了以下文件,您现在可以使用这些文件deploy一个新的Prisma服务:

  • datamodel.prisma:包含基于现有数据库生成的数据模型(在SDL中)。
  • docker-compose.yml:包含Prisma服务器配置的Docker Compose文件,包括有关如何连接数据库的详细信息
  • prisma.yml:服务的根配置文件

为了能够使用Prisma查询MongoDB数据库,您现在需要deploy服务并打开GraphQL Playground:


prisma deploy
prisma playground

prisma introspect的工作方式与prisma init向导类似,因为您需要提供数据库连接信息。

prisma init向导生成一个完整的service配置,prisma introspect只生成datamodel文件:

  • datamodel-[TIMESTAMP] .prisma:时间戳组件允许您在不覆盖现有数据模型的情况下对现有Prisma服务使用introspect命令。

    Introspection目前仅支持PostgreSQL和MongoDB。 有一个待处理的feature request也可以为MySQL带来introspect。