使用 NestJS 在 PostgreSQL 数据库中存储文件

Posted

技术标签:

【中文标题】使用 NestJS 在 PostgreSQL 数据库中存储文件【英文标题】:Storing file in PostgreSQL database using NestJS 【发布时间】:2021-12-17 14:38:51 【问题描述】:

我在 React 中有一个表单。它有很多领域。一旦用户单击submit 按钮,所有字段都应保存在database 中。它还包含一个file attachment(pdf)

我不知道将存储文件的变量的数据类型是什么,我应该在实体类中使用。还有什么应该是数据库列类型。我也在使用 TypeORM。

   @IsNotEmpty()
    @IsDate()
    endDate: Date;
    @Column()
    @IsNotEmpty()
    @IsString()
    personIncharge: string;

    @Column()
    @IsNotEmpty()
    @IsString()
    country: string;

    @Column()
    @IsNotEmpty()
    @IsString()
    comments: string;

    attachFile: string;  // Should I take file or string?

【问题讨论】:

【参考方案1】:

您可能会在*** comment 中找到您的解决方案

基本上,您在 TypeORM 注释中将列类型转换为 blob 或 longblob,然后在实体字段中使用类型 Buffer

@Column(type: 'longblob')
attachFile: Buffer;

然后您将能够按照帖子示例中所示提供文件:

app.get("/file/:id", async (req, res)=>
    try 
        const repo = getConnection().getRepository(MYFile)
        const result_find = await repo.findOne(req.params.id)
        console.log(result_find);
        var fileData = result_find.data;
        res.writeHead(200, 
        'Content-Type': result_find.mimeType,
        'Content-Disposition': 'attachment; filename=' + result_find.name,
        'Content-Length': fileData.length
        );
        res.write(fileData);
        res.end();
     catch (error) 
        console.log(error)
        res.send("ERROR")
    
)

【讨论】:

longblob 在 postgres 中不存在。相反,它将是 bytea。你能指导我使用nestjs typeorm而不是express吗?你能指导我创建上面的表格并使用nestjs/typeorm在postgres中上传文件吗【参考方案2】:

如果你想使用字符串,客户端必须发送base64文件到后端。 格式:data:(mimetype);(charset),(encoded) -> data:image/png;base64,\ee\9f920d....

这里的解决方案,使用base64字符串 DTO(数据传输对象)

import  IsDefined, IsNotEmpty  from 'class-validator';

export class UpdateUserAvatarDto 
  @IsDefined()
  @IsNotEmpty()
  file: string;

控制器

@UseGuards(JwtAuthGuard)
@Patch('account/avatar')
async updateAvatar(
    @User() user: Payload,
    @Body() updateUserAvatarDto: UpdateUserAvatarDto,
    @Res() res: Response,
  ) 
    try 
      const  file  = updateUserAvatarDto;

      createFile(file,  prefix: ['user', 'avatar'], name: user.id ); // file is string base64 you can store it to database.

      return response(res, HttpStatus.OK, 
        message: 'Successfully update avatar',
      );
     catch (e) 
      console.error(e);
      return response(res, HttpStatus.INTERNAL_SERVER_ERROR, 
        message: e,
        data: null,
      );
    

如果你想从 base64 创建文件

export const createFile = async (base64,  prefix, name ) => 
  const cleanBase64 = base64.split(',')[1];
  const buffer = Buffer.from(cleanBase64, 'base64');
  const file = await fileType.fromBuffer(buffer);
  return fs.writeFileSync(
    path.join(
      path.resolve('./'),
      ...['public', ...prefix, `$name.$file.ext`],
    ),
    buffer,
  );
;

【讨论】:

以上是关于使用 NestJS 在 PostgreSQL 数据库中存储文件的主要内容,如果未能解决你的问题,请参考以下文章

NestJS/TypeORM:无法读取未定义的属性“createQueryBuilder”

迁移文件中的 NestJS TypeORM 语法错误

在 main.ts 中使用 .env 文件中的数据 - NestJS

NestJS + TypeORM:使用两个或更多数据库?

在没有实际访问数据库的情况下测试使用 Prisma 的 NestJS 服务

nestjs使用Typeorm实现数据库CRUD操作