3个技巧!Prisma DateTime字段默认值设置避坑指南

3个技巧!Prisma DateTime字段默认值设置避坑指南

【免费下载链接】prisma Next-generation ORM for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, MongoDB and CockroachDB 【免费下载链接】prisma 项目地址: https://gitcode.com/GitHub_Trending/pr/prisma

你还在为Prisma中DateTime字段的默认值设置烦恼吗?设置不当导致的时区混乱、数据不一致等问题是否让你头疼?本文将通过3个实用技巧,带你掌握DateTime字段默认值的最佳实践,轻松避开常见陷阱。读完本文,你将学会如何正确设置创建时间、自动更新时间戳,以及处理不同数据库环境下的时区问题。

Prisma ORM简介

Prisma ORM(对象关系映射,Object-Relational Mapping)是下一代Node.js和TypeScript的ORM工具,支持PostgreSQL、MySQL、SQLite等多种数据库。其核心是通过Prisma模式(schema)文件定义数据模型,自动生成类型安全的查询构建器,简化数据库操作。

Prisma依赖关系

Prisma的主要组件包括Prisma Client(查询构建器)、Prisma Migrate(数据库迁移工具)和Prisma Studio(可视化数据管理工具)。更多信息可参考官方文档

技巧一:使用now()设置创建时间默认值

在Prisma中,最常用的DateTime字段默认值设置是使用now()函数,它会自动获取数据库服务器的当前时间作为默认值。

基本用法

model User {
  id        Int      @id @default(autoincrement())
  name      String
  email     String   @unique
  createdAt DateTime @default(now()) // 创建时间默认值
}

上述代码中,createdAt字段使用@default(now())设置默认值,当新记录插入时,该字段会自动填充为当前时间。

实际项目示例

在Prisma的测试用例中,我们可以看到大量使用now()设置创建时间的示例:

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  published Boolean  @default(false)
  createdAt DateTime @default(now()) // 使用now()设置默认时间
  updatedAt DateTime @updatedAt
  authorId  Int
  author    User     @relation(fields: [authorId], references: [id])
}

代码来源:packages/client/src/tests/integration/happy/disconnect-finally/schema.prisma

注意事项

  • now()返回的是数据库服务器的时间,而非应用服务器时间
  • 默认情况下,时间以UTC时区存储,与数据库配置相关
  • 适用于大多数需要记录创建时间的场景

技巧二:使用@updatedAt自动更新时间戳

除了记录创建时间,我们经常需要跟踪记录的最后更新时间。Prisma提供了@updatedAt属性,用于自动更新字段值为当前时间。

基本用法

model Product {
  id        Int      @id @default(autoincrement())
  name      String
  price     Float
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt // 自动更新时间戳
}

当记录被更新时,updatedAt字段会自动更新为当前时间,无需手动干预。

实际项目示例

在Prisma的测试代码中,createdAtupdatedAt通常一起使用:

model Account {
  id        Int      @id @default(autoincrement())
  username  String   @unique
  email     String   @unique
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt // 自动更新时间戳
  lastLogin DateTime?
}

代码来源:packages/client/src/tests/integration/happy/groupBy/schema.prisma

工作原理

@updatedAt是Prisma的特殊属性,其工作原理如下:

  1. 当创建记录时,该字段会被设置为与createdAt相同的值
  2. 当更新记录时,Prisma会自动将该字段更新为当前时间
  3. 此行为由Prisma Client在运行时自动处理,无需数据库触发器

技巧三:处理时区和数据库差异

不同数据库对DateTime类型的处理存在差异,特别是在时区方面。Prisma提供了灵活的方式来处理这些差异。

时区处理最佳实践

Prisma推荐将所有时间存储为UTC时间,在应用层进行时区转换:

// 保存UTC时间(由Prisma自动处理)
const newUser = await prisma.user.create({
  data: {
    name: "John Doe",
    email: "john@example.com"
    // createdAt会自动设置为UTC时间
  }
});

// 应用层转换为时区时间
const localTime = new Date(newUser.createdAt).toLocaleString('zh-CN', {
  timeZone: 'Asia/Shanghai'
});

不同数据库的DateTime处理

PostgreSQL

PostgreSQL支持时区感知的DateTime类型,可在schema中指定:

model Event {
  id        Int      @id @default(autoincrement())
  name      String
  startTime DateTime @db.Timestamp(6) // 带时区的时间戳
}

代码来源:packages/bundle-size/schema.postgres.prisma

MySQL

MySQL的DateTime类型不带时区信息,存储的是本地时间:

model Event {
  id        Int      @id @default(autoincrement())
  name      String
  startTime DateTime @db.Timestamp(6) // 不带时区的时间戳
}

代码来源:packages/bundle-size/schema.mysql.prisma

数据库迁移注意事项

使用Prisma Migrate进行数据库迁移时,需注意DateTime字段的默认值设置:

// 迁移文件示例 (migrations/20230928000000_add_created_at_field/migration.sql)
ALTER TABLE "User" ADD COLUMN "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

Prisma Migrate会根据schema自动生成类似上述的迁移SQL。更多迁移相关信息,请参考Prisma Migrate文档

常见陷阱与解决方案

陷阱1:混用应用层时间和数据库时间

问题:有时开发者会在代码中手动生成时间戳,再传给Prisma:

// 不推荐的做法
const newUser = await prisma.user.create({
  data: {
    name: "John Doe",
    email: "john@example.com",
    createdAt: new Date() // 应用层生成时间
  }
});

解决方案:使用@default(now())让数据库生成时间,避免分布式系统中的时间不一致问题。

陷阱2:修改@updatedAt行为

问题:试图手动修改@updatedAt字段的值:

// 无效的操作
const updatedUser = await prisma.user.update({
  where: { id: 1 },
  data: {
    name: "Jane Doe",
    updatedAt: new Date("2023-01-01") // 手动设置updatedAt
  }
});

解决方案@updatedAt会自动更新,无需手动设置。如需记录特定时间,应创建额外字段(如lastModifiedAt)。

陷阱3:忽视数据库时区配置

问题:数据库服务器时区与应用服务器时区不一致,导致时间显示异常。

解决方案

  1. 确保数据库服务器使用UTC时区
  2. 在连接字符串中明确指定时区:
datasource db {
  provider = "postgresql"
  url      = "postgresql://user:password@localhost:5432/mydb?schema=public&timezone=UTC"
}

总结与最佳实践清单

通过本文介绍的3个技巧,你应该已经掌握了Prisma中DateTime字段默认值设置的要点。以下是最佳实践清单,帮助你在实际项目中正确应用:

最佳实践清单

  1. 创建时间:使用@default(now())让数据库自动设置创建时间
  2. 更新时间:使用@updatedAt属性自动跟踪记录更新时间
  3. 时区处理:始终以UTC存储时间,在应用层进行时区转换
  4. 数据库差异:根据目标数据库类型(PostgreSQL/MySQL等)调整字段定义
  5. 迁移注意:使用Prisma Migrate管理 schema 变更,确保默认值正确应用

下一步学习

想要深入了解Prisma的更多功能?推荐查阅以下资源:

掌握这些DateTime字段默认值设置技巧后,你的Prisma项目将更加健壮和可维护。如果觉得本文对你有帮助,请点赞、收藏并关注我们,获取更多Prisma实用技巧!下一期我们将介绍Prisma中的关系模型设计最佳实践,敬请期待。

【免费下载链接】prisma Next-generation ORM for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, MongoDB and CockroachDB 【免费下载链接】prisma 项目地址: https://gitcode.com/GitHub_Trending/pr/prisma

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值