首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >TypeORM:主列的默认值

TypeORM:主列的默认值
EN

Stack Overflow用户
提问于 2021-06-04 21:47:24
回答 1查看 7.9K关注 0票数 2

当试图使用TypeORM (在NestJ中)将带有默认值的主列的实体保存到DB时,我遇到了问题。

TL;博士--在default似乎什么都不做的情况下,如何用TypeORM设置默认列值?

编辑1:好的,所以default似乎是DB级的,以前有点漏掉了,但是@BeforeInsert()仍然应该做到这一点(但没有)。

编辑2:很明显,@BeforeInsert()钩子起作用,但只有在使用.save(new UserSession(userId))而不是.save({ userId: userId })调用.save() (当然需要在UserSession中使用适当的构造函数)时才能工作。

设置

我有一个实体UserSession,注意sessionId字段,它应该有一个默认值,不管cryptoRandomString({ length: 128, type: 'alphanumeric' })返回什么。

代码语言:javascript
运行
复制
@Entity('user_session')
export class UserSession {
    
    @PrimaryColumn({ 
        name: 'session_id',
        default: () => cryptoRandomString({ length: 128, type: 'alphanumeric' })
    })
    sessionId: string
    
    @Column({ 
        name: 'user_id',
    })
    userId: string
   
}

然后,我使用TypeORM存储库.save()函数将对象写入数据库,如下所示:

代码语言:javascript
运行
复制
@Injectable()
export class AuthService {
    constructor(
        @InjectRepository(UserSession)
        private readonly userSessionRepository: Repository<UserSession>
    ) {}

    async createNewSession(userId: string): Promise<void> {
        // Create new session
        const session = await this.userSessionRepository.save({
            userId: userId
        })

       // If only it got that far...
    }
}

误差

此时,如果没有“手动”设置,我希望TypeORM可以为sessionId设置一个默认值。但是,它只抛出一个错误:

代码语言:javascript
运行
复制
[Nest] 23088   - 04/06/2021, 23:18:44   [ExceptionsHandler] ER_NO_DEFAULT_FOR_FIELD: Field 'session_id' doesn't have a default value +4032ms
QueryFailedError: ER_NO_DEFAULT_FOR_FIELD: Field 'session_id' doesn't have a default value
    at new QueryFailedError (E:\SAC\projects\api-flexrent\node_modules\typeorm\error\QueryFailedError.js:12:28)
    at Query.<anonymous> (E:\SAC\projects\api-flexrent\node_modules\typeorm\driver\mysql\MysqlQueryRunner.js:217:45)
    at Query.<anonymous> (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\Connection.js:526:10)
    at Query._callback (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\Connection.js:488:16)
    at Query.Sequence.end (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24)
    at Query.ErrorPacket (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\protocol\sequences\Query.js:92:8)
    at Protocol._parsePacket (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\protocol\Protocol.js:291:23)
    at Parser._parsePacket (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\protocol\Parser.js:433:10)
    at Parser.write (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\protocol\Parser.js:43:10)
    at Protocol.write (E:\SAC\projects\api-flexrent\node_modules\mysql\lib\protocol\Protocol.js:38:16)

绝望

在花了一段时间在好的旧谷歌上之后,我尝试了几种不同的版本,它们都不起作用(并且抛出了相同的错误):

代码语言:javascript
运行
复制
@PrimaryColumn({ 
    name: 'session_id',
    default: cryptoRandomString({ length: 128, type: 'alphanumeric' })
})
sessionId: string

代码语言:javascript
运行
复制
@PrimaryColumn({ 
    name: 'session_id',
    default: () => 'cryptoRandomString({ length: 128, type: "alphanumeric" })' // Why would that even work
})
sessionId: string

代码语言:javascript
运行
复制
@PrimaryColumn({ 
    name: 'session_id',
    default: 'cryptoRandomString({ length: 128, type: "alphanumeric" })' // Why would that even work
})
sessionId: string

代码语言:javascript
运行
复制
@PrimaryColumn({ 
    name: 'session_id',
    default: 'please work'
})
sessionId: string

或者不是在@PrimaryColumn()中设置@BeforeInsert(),而是使用@BeforeInsert(),这显然不是在使用.save()时调用的

代码语言:javascript
运行
复制
@BeforeInsert()
beforeInsertAction(): void {
    this.sessionId = cryptoRandomString({ length: 128, type: 'alphanumeric' })
}

唯一起作用的是为UserSession类使用构造函数并在其中设置sessionId (我认为这有点违背了TypeORM中default值的目的?):

代码语言:javascript
运行
复制
constructor(
    userId: string
) {
    this.userId = userId
    this.sessionId = cryptoRandomString({ length: 128, type: 'alphanumeric' })
}

把它称为

代码语言:javascript
运行
复制
const session = await this.userSessionRepository.save(new UserSession(userId))

我错过什么了吗?一开始,我是不是完全搞错了?我再也不知道了。

EN

Stack Overflow用户

回答已采纳

发布于 2022-02-18 22:02:31

我最终找到了解决问题的方法.

我现在像这样定义我的实体类:

代码语言:javascript
运行
复制
@Entity('user')
export class User {

  @PrimaryColumn({ 
    name: 'user_id',
    type: 'varchar',
    length: 32
  })
  userId: string = cryptoRandomString({ length: 32, type: 'alphanumeric' })

  @Column({ 
    name: 'session_id',
    type: 'varchar',
    length: 128
  })
  sessionId: string = cryptoRandomString({ length: 128, type: 'alphanumeric' })

  @Column({ 
    name: 'email',
    type: 'varchar',
    length: 128
  })
  email: string

}

现在我可以使用存储库的.create()创建新的用户实体了

代码语言:javascript
运行
复制
const user: User = this.userRepo.create({ email: 'hello.world@example.com' })

它创建以下对象:

代码语言:javascript
运行
复制
user: {
  userId: 'ivWW8oMGD8oMh2FL0vM3Grrh2FL0M3Di'
  sessionId: 'vM3DiW8oMGrh2FL0vM3DiW8oMGrh2FL0vM3DiW8oMGrh2FL0vM3DiW8oMGrh2FL0...'
  email: 'hello.world@example.com'
}

然后,可以使用.save()方法再次保存以下内容:

代码语言:javascript
运行
复制
await this.userRepo.save(user)
票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67844341

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档