Sequelize-Typescript 与存储库的一对多关联在存在多个子实体时返回 1 个

问题描述 投票:0回答:1

我一直在使用 Sequelize-Typescript,并且偶然发现了一对多关联。这里我有“相册”和“照片”作为我的实体。一张“相册”有很多“照片”。所以这是我的实体代码供您参考:

专辑.ts

`

@Table({
  timestamps: true,
  deletedAt: "albumDeletedAt",
  paranoid: true,
  createdAt: true,
  updatedAt: true
})
export class Album extends Model {
  @PrimaryKey
  @Column({
      type: DataType.INTEGER,
      primaryKey: true,
      autoIncrement: true
  })
  declare id: number;

  @Column({
      type: DataType.STRING,
      allowNull: false
  })
  declare name: string;

  @Column({
     type: DataType.STRING,
     allowNull: true
  })
  declare description?: string;

  @Column({
      type: DataType.STRING,
      allowNull: false
  })
  declare thumbnailURL: string;

  @HasMany(() => Photo)
  declare photos: Photo[];

  @CreatedAt
  declare createdAt: Date;

  @UpdatedAt
  declare updatedAt: Date;
 }`

照片.ts

import { BelongsTo, Column, CreatedAt, DataType, ForeignKey, Model, PrimaryKey, Table, 
UpdatedAt } from "sequelize-typescript";
import { Album } from "./album";

@Table({
  timestamps: true,
  deletedAt: "photoDeletedAt",
  paranoid: true,
  createdAt: true,
  updatedAt: true
})
export class Photo extends Model {
  @PrimaryKey
  @Column({
      type: DataType.INTEGER,
      primaryKey: true,
      autoIncrement: true
  })
  declare id: number;

  @Column({
     type: DataType.STRING,
     allowNull: false
  })
  declare name: string;

  @Column({
     type: DataType.STRING,
     allowNull: false
  })
  declare photoURL: string;

  @ForeignKey(() => Album)
  @Column({
     type: DataType.INTEGER,
     allowNull: true,
  })
  declare albumId: number;

  @BelongsTo(() => Album)
  declare album: Album;

  @CreatedAt
  declare createdAt: Date;

  @UpdatedAt
  declare updatedAt: Date;
}

AlbumRepository.ts

export class AlbumRepository {
private albumRepository: Repository<Album>;
private photoRepository: Repository<Photo>;

/**
 * This constructor injects the DatabaseMiddleware class created and annotated as "@Service()"
 * @param databaseMiddleware Database Middleware created
 */
constructor(public databaseMiddleware: DatabaseMiddleware) {
    this.albumRepository = databaseMiddleware.getDatabaseInstance().getRepository(Album);
    this.photoRepository = databaseMiddleware.getDatabaseInstance().getRepository(Photo);
}

/**
 * Creates an "Album" data in the database.
 * @param albumCreateDTO Album Create DTO data model
 * @returns "Album" data entity model (if successfully created in the database) or null.
 */
public async createAlbum(albumCreateDTO: AlbumCreateDto) {
    try {
        return await this.albumRepository.create({ ...albumCreateDTO }, { include: [this.photoRepository] });
    } catch (error) {
        console.error("Error while creating an album data to the database due to", error?.message);
        return null;
    }
}

/**
 * Find the album via it's ID
 * @param id The ID of the album
 * @returns Album (if exists) or null
 */
public async getAlbumById(id: number) : Promise<Album | null> {
    try {
        return await this.albumRepository.findByPk(id, { include: [this.photoRepository] }) ?? null;
    } catch (error) {
        console.error(`Error finding the album via ID for the ID of ${id} due to`, error);
        return null;
    }
}

}

最后,我的 Sequelize-Typescript 实例如下:

export default class DatabaseMiddleware {
private databaseInstance: Sequelize;

constructor() {
    this.databaseInstance = new Sequelize({
        dialect: "mysql",
        host: process.env.DATABASE_HOST,
        database: process.env.DATABASE_NAME,
        username: process.env.DATABASE_USERNAME,
        password: process.env.DATABASE_PASSWORD,
        port: 3306,
        // storage: process.env.DATABASE_STORAGE_PATH,
        logging(sql, timing) {
            console.log("The SQL statement from Sequelize executed is", sql, timing);
        },
        query: { raw: true }
        models: [User, Album, Video, Photo],
        repositoryMode: true
    });
}

public async connectToDatabase() {
    try {
        await this.databaseInstance.authenticate();
        if (process.env.ENVIRONMENT_PROFILE === "development") {
            await this.databaseInstance.sync({ alter: true, force: true });
        }
        console.log("Connection to database has been established successfully");
    } catch (error) {
        console.error("Unable to connect to database due to", error);
    }
}

public getDatabaseInstance() {
    return this.databaseInstance;
}

}

我使用基于类的样式来创建 Express.JS REST API,并且在除实体之外使用的每个类中添加依赖项注入。我可以使用“照片”创建一个“相册”,并且可以在数据库中看到它。但当我调用存储库中的

getAlbumById
函数时,我只得到 1 张“照片”。如果我插入了 3 个“照片”,那么在调用该函数期间,当数据库中有 3 个“照片”时,它仅返回 1 个“照片”。

更新问题描述

以下是在

include: [this.photoRepository]
中使用
AlbumRepository.ts
运行查询后的样子。

第一个截图

第二张截图

如果您有任何解决方案,请在这里分享。谢谢!

从函数

raw: true
中删除
AlbumRepository.ts
标志时出错:

由于 TypeError,通过 ID 查找 ID 为 1 的相册时出错:result.get 不是函数 位于 E:\Coding Projects\Projects\Back-Ends\Profilic ode_modules\sequelize\src\model.js:1885:39 在Array.reduce() 位于 E:\Coding Projects\Projects\Back-Ends\Profilic ode_modules\sequelize\src\model.js:1884:19 在Array.map() 在 Function._findSeparate (E:\Coding Projects\Projects\Back-Ends\Profilic ode_modules\sequelize\src\model.js:1881:39) 在 Function.findAll (E:\Coding Projects\Projects\Back-Ends\Profilic ode_modules\sequelize\src\model.js:1840:24) 在 processTicksAndRejections (节点:内部/进程/task_queues:95:5) 在 async Function.findOne (E:\Coding Projects\Projects\Back-Ends\Profilic ode_modules\sequelize\src\model.js:1998:12) 在 async Function.findByPk (E:\Coding Projects\Projects\Back-Ends\Profilic ode_modules\sequelize\src\model.js:1955:12) 在异步AlbumRepository.getAlbumById (E:\Coding Projects\Projects\Back-Ends\Profilic 存储库 lbum.repository.ts:52:20)

node.js typescript express sequelize.js sequelize-typescript
1个回答
0
投票

解决方案是在交易中添加

getAlbumByID

。例如:

raw: true, nest: true

.

我想要的结果现在如下所示:

const searchedResult = await this.albumRepository.findByPk(id, { include: [this.photoRepository], raw: true, nest: true });

}

这是因为sequelize-typescript 使用一个库通过添加子对象和子属性来安全地反序列化子对象。例如:

{ "name": "My Album", "description": "Personal Album", "thumbnailURL": "http://localhost:8080/uploads/pictures/my_album/my_album_thumbnail.jpg", "photos": { "id": 1, "name": "3840x2880_2887b808096152458f8e6b41cb5a8780.jpg", "photoURL": "http://192.168.1.15:8080/uploads/pictures/my_album/3840x2880_2887b808096152458f8e6b41cb5a8780.jpg", "albumId": 1, "createdAt": "2024-03-15T11:34:45.000Z", "updatedAt": "2024-03-15T11:34:45.000Z", "photoDeletedAt": null }, "albumDeletedAt": null

标志

"photos.id": 1

,将其转换为拥有子对象的常规方式。现在,我提到了这个错误。因为在我的问题描述中,我有一对多的关系,即一个

nest: true
可以有一个或多个
Album.ts
。现在,在我的数据库中,即使我有 3 个
Photo.ts
相同的外键
Photo.ts
,它仍然返回我相册中的一张照片。此错误在 GitHub 的拉取请求问题中报告:
一对多关系中的错误问题
。否则,一切正常。再次感谢那些提供帮助的人。 解决方案的 GitHub 链接:

导致此解决方案的讨论

© www.soinside.com 2019 - 2024. All rights reserved.