Skip to main content

构建你的架构原型

Prisma CLI 有一个用于原型设计模式的专用命令:db push

¥The Prisma CLI has a dedicated command for prototyping schemas: db push

db push 使用与 Prisma Migrate 相同的引擎来同步你的 Prisma 架构与数据库架构。db push 命令:

¥db push uses the same engine as Prisma Migrate to synchronize your Prisma schema with your database schema. The db push command:

  1. 内省数据库以推断并执行使数据库架构反映 Prisma 架构状态所需的更改。

    ¥Introspects the database to infer and executes the changes required to make your database schema reflect the state of your Prisma schema.

  2. 默认情况下,将更改应用于数据库模式后,会触发生成器(例如,Prisma 客户端)。你不需要手动调用 prisma generate

    ¥By default, after changes have been applied to the database schema, generators are triggered (for example, Prisma Client). You do not need to manually invoke prisma generate.

  3. 如果 db push 预计更改可能会导致数据丢失,它将:

    ¥If db push anticipates that the changes could result in data loss, it will:

    • 抛出错误

      ¥Throw an error

    • 如果你仍想进行更改,则需要 --accept-data-loss 选项

      ¥Require the --accept-data-loss option if you still want to make the changes

注意:

¥Notes:

  • db push 不与迁移交互或依赖迁移。不会创建或更新迁移表 _prisma_migrations,也不会生成迁移文件。

    ¥db push does not interact with or rely on migrations. The migrations table _prisma_migrations will not be created or updated, and no migration files will be generated.

  • 使用 PlanetScale 时,我们建议你使用 db push 而不是 migrate。有关详细信息,请参阅我们的入门文档,根据你的情况选择 从零开始添加到现有项目

    ¥When working with PlanetScale, we recommend that you use db push instead of migrate. For details refer to our Getting Started documentation, either Start from scratch or Add to existing project depending on your situation.

选择 db push 或 Prisma Migrate

¥Choosing db push or Prisma Migrate

db push 工作良好,如果:

¥db push works well if:

  • 你希望在本地快速构建原型并迭代架构设计,而不需要将这些更改部署到其他环境(例如其他开发者或登台和生产环境)。

    ¥You want to quickly prototype and iterate on schema design locally without the need to deploy these changes to other environments such as other developers, or staging and production environments.

  • 你优先考虑达到所需的最终状态,而不是为达到该最终状态而执行的更改或步骤(无法预览 db push 所做的更改)

    ¥You are prioritizing reaching a desired end-state and not the changes or steps executed to reach that end-state (there is no way to preview changes made by db push)

  • 你不需要控制架构更改如何影响数据。无法编排架构和数据迁移 — 如果 db push 预计更改将导致数据丢失,你可以使用 --accept-data-loss 选项接受数据丢失或停止该过程。无法自定义更改。

    ¥You do not need to control how schema changes impact data. There is no way to orchestrate schema and data migrations—if db push anticipates that changes will result in data loss, you can either accept data loss with the --accept-data-loss option or stop the process. There is no way to customize the changes.

有关如何以这种方式使用 db push 的示例,请参阅 使用 db push 进行架构原型设计

¥See Schema prototyping with db push for an example of how to use db push in this way.

如果出现以下情况,则不建议使用 db push

¥db push is not recommended if:

  • 你希望在其他环境中复制架构更改而不丢失数据。你可以使用 db push 进行原型设计,但你应该使用迁移来提交架构更改并将其应用到你的其他环境中。

    ¥You want to replicate your schema changes in other environments without losing data. You can use db push for prototyping, but you should use migrations to commit the schema changes and apply these in your other environments.

  • 你希望对架构更改的执行方式进行细粒度控制 - 例如,重命名一列,而不是删除它并创建一个新列

    ¥You want fine-grained control over how the schema changes are executed - for example, renaming a column instead of dropping it and creating a new one.

  • 你希望跟踪一段时间内对数据库架构所做的更改。db push 不会创建任何允许你跟踪这些更改的工件。

    ¥You want to keep track of changes made to the database schema over time. db push does not create any artifacts that allow you to keep track of these changes.

  • 你希望架构更改是可逆的。你可以再次使用 db push 恢复到原始状态,但这可能会导致数据丢失。

    ¥You want the schema changes to be reversible. You can use db push again to revert to the original state, but this might result in data loss.

我可以同时使用 Prisma Migrate 和 db push 吗?

¥Can I use Prisma Migrate and db push together?

是的,你可以 在你的开发工作流程中一起使用 db push 和 Prisma Migrate 。 例如,你可以:

¥Yes, you can use db push and Prisma Migrate together in your development workflow . For example, you can:

  • 在项目开始时使用 db push 制作模式原型,并在你对初稿感到满意时初始化迁移历史记录

    ¥Use db push to prototype a schema at the start of a project and initialize a migration history when you are happy with the first draft

  • 使用 db push 对现有架构进行原型更改,然后运行 prisma migrate dev 从你的更改生成迁移(系统将要求你重置)

    ¥Use db push to prototype a change to an existing schema, then run prisma migrate dev to generate a migration from your changes (you will be asked to reset)

构建新模式原型

¥Prototyping a new schema

以下场景演示了如何使用 db push 将新模式与空数据库同步,并演进该模式 - 包括当 db push 检测到更改会导致数据丢失时会发生什么。

¥The following scenario demonstrates how to use db push to synchronize a new schema with an empty database, and evolve that schema - including what happens when db push detects that a change will result in data loss.

  1. 创建架构的初稿:

    ¥Create a first draft of your schema:

    generator client {
    provider = "prisma-client-js"
    }

    datasource db {
    provider = "postgresql"
    url = env("DATABASE_URL")
    }

    model User {
    id Int @id @default(autoincrement())
    name String
    jobTitle String
    posts Post[]
    profile Profile?
    }

    model Profile {
    id Int @id @default(autoincrement())
    biograpy String // Intentional typo!
    userId Int @unique
    user User @relation(fields: [userId], references: [id])
    }

    model Post {
    id Int @id @default(autoincrement())
    title String
    published Boolean @default(true)
    content String @db.VarChar(500)
    authorId Int
    author User @relation(fields: [authorId], references: [id])
    categories Category[]
    }

    model Category {
    id Int @id @default(autoincrement())
    name String @db.VarChar(50)
    posts Post[]

    @@unique([name])
    }
  2. 使用 db push 将初始模式推送到数据库:

    ¥Use db push to push the initial schema to the database:

    npx prisma db push
  3. 创建一些示例内容:

    ¥Create some example content:

    const add = await prisma.user.create({
    data: {
    name: 'Eloise',
    jobTitle: 'Programmer',
    posts: {
    create: {
    title: 'How to create a MySQL database',
    content: 'Some content',
    },
    },
    },
    })
  4. 进行附加更改 - 例如,创建一个新的必填字段:

    ¥Make an additive change - for example, create a new required field:

    // ... //

    model Post {
    id Int @id @default(autoincrement())
    title String
    description String
    published Boolean @default(true)
    content String @db.VarChar(500)
    authorId Int
    author User @relation(fields: [authorId], references: [id])
    categories Category[]
    }

    // ... //
  5. 推送更改:

    ¥Push the changes:

    npx prisma db push

    db push 将失败,因为除非你提供默认值,否则你无法将必填字段添加到具有现有内容的表中。

    ¥db push will fail because you cannot add a required field to a table with existing content unless you provide a default value.

  6. 重置数据库中的所有数据并重新应用迁移。

    ¥Reset all data in your database and re-apply migrations.

    npx prisma migrate reset

    注意:与 Prisma Migrate 不同,db push 不会生成可以修改以保留数据的迁移,因此最适合在开发环境中进行原型设计。

    ¥Note: Unlike Prisma Migrate, db push does not generate migrations that you can modify to preserve data, and is therefore best suited for prototyping in a development environment.

  7. 继续发展你的模式,直到达到相对稳定的状态。

    ¥Continue to evolve your schema until it reaches a relatively stable state.

  8. 初始化迁移历史:

    ¥Initialize a migration history:

    npx prisma migrate dev --name initial-state

    达到初始原型所采取的步骤不会被保留 - db push 不生成历史记录。

    ¥The steps taken to reach the initial prototype are not preserved - db push does not generate a history.

  9. 将你的迁移历史记录和 Prisma 架构推送到源代码控制(例如 Git)。

    ¥Push your migration history and Prisma schema to source control (e.g. Git).

此时,原型设计的最终草案将保留在迁移中,并且可以推送到其他环境(测试、生产或团队的其他成员)。

¥At this point, the final draft of your prototyping is preserved in a migration and can be pushed to other environments (testing, production, or other members of your team).

使用现有迁移历史进行原型设计

¥Prototyping with an existing migration history

以下场景演示了如何使用 db push 对已存在迁移历史记录的 Prisma 架构进行原型更改。

¥The following scenario demonstrates how to use db push to prototype a change to a Prisma schema where a migration history already exists.

  1. 查看最新的 Prisma 架构和迁移历史记录:

    ¥Check out the latest Prisma schema and migration history:

    generator client {
    provider = "prisma-client-js"
    }

    datasource db {
    provider = "postgresql"
    url = env("DATABASE_URL")
    }

    model User {
    id Int @id @default(autoincrement())
    name String
    jobTitle String
    posts Post[]
    profile Profile?
    }

    model Profile {
    id Int @id @default(autoincrement())
    biograpy String // Intentional typo!
    userId Int @unique
    user User @relation(fields: [userId], references: [id])
    }

    model Post {
    id Int @id @default(autoincrement())
    title String
    published Boolean @default(true)
    content String @db.VarChar(500)
    authorId Int
    author User @relation(fields: [authorId], references: [id])
    categories Category[]
    }

    model Category {
    id Int @id @default(autoincrement())
    name String @db.VarChar(50)
    posts Post[]

    @@unique([name])
    }
  2. 对新功能进行原型设计,这可能涉及任意数量的步骤。例如,你可能:

    ¥Prototype your new feature, which can involve any number of steps. For example, you might:

    • 创建 tags String[] 字段,然后运行 db push

      ¥Create a tags String[] field, then run db push

    • 将字段类型更改为 tags Tag[] 并添加名为 Tag 的新模型,然后运行 db push

      ¥Change the field type to tags Tag[] and add a new model named Tag, then run db push

    • 改变主意,恢复原来的 tags String[] 字段,然后调用 db push

      ¥Change your mind and restore the original tags String[] field, then call db push

    • 手动更改数据库中的 tags 字段 - 例如,添加约束

      ¥Make a manual change to the tags field in the database - for example, adding a constraint

    在尝试了多种解决方案后,最终的架构更改如下所示:

    ¥After experimenting with several solutions, the final schema change looks like this:

    model Post {
    id Int @id @default(autoincrement())
    title String
    description String
    published Boolean @default(true)
    content String @db.VarChar(500)
    authorId Int
    author User @relation(fields: [authorId], references: [id])
    categories Category[]
    tags String[]
    }
  3. 要创建添加新 tags 字段的迁移,请运行 migrate dev 命令:

    ¥To create a migration that adds the new tags field, run the migrate dev command:

    npx prisma migrate dev --name added-tags

    Prisma Migrate 将提示你重置,因为你在原型制作时手动和使用 db push 所做的更改不属于迁移历史记录的一部分:

    ¥Prisma Migrate will prompt you to reset because the changes you made manually and with db push while prototyping are not part of the migration history:

    √ Drift detected: Your database schema is not in sync with your migration history.

    We need to reset the PostgreSQL database "prototyping" at "localhost:5432".
    警告

    这将导致数据完全丢失。

    ¥This will result in total data loss.

    npx prisma migrate reset
  4. Prisma Migrate 会重播现有的迁移历史记录,根据你的架构更改生成新的迁移,并将这些更改应用到数据库。

    ¥Prisma Migrate replays the existing migration history, generates a new migration based on your schema changes, and applies those changes to the database.

提示

使用 migrate dev 时,如果你的架构更改意味着种子脚本将不再工作,你可以使用 --skip-seed 标志来忽略种子脚本。

¥When using migrate dev, if your schema changes mean that seed scripts will no longer work, you can use the --skip-seed flag to ignore seed scripts.

此时,原型设计的最终结果将保留在迁移中,并且可以推送到其他环境(测试、生产或团队的其他成员)。

¥At this point, the final result of your prototyping is preserved in a migration, and can be pushed to other environments (testing, production, or other members of your team).