TypeORM 插入带有外键的行

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

我之间有一个@OneToMany关系
聊天室 < 1 ---- M > 消息
我遇到的问题是,每当我尝试插入一条消息(或大量消息)时, ChatRoom 的外键为空。
此外,我正在上传我的设置。

@Entity("messages")
export class Message {

    @PrimaryColumn()
    id: string;

    @ManyToOne(() => ChatRoom, chatroom => chatroom.messages)
    chatRoom: ChatRoom | undefined

    @Column({nullable: false})
    message: string;

    @Column({nullable: false})
    receiver: string;

    @Column({nullable: false})
    created_utc: Date;
}
@Entity("chatrooms")
export class ChatRoom {

    @PrimaryColumn()
    id: string;

    @OneToMany(() => Message, message => message.chatRoom, {
        cascade: ["insert", "remove"]
    })
    @JoinColumn({name: 'id'})
    messages: Message[];

    @Column()
    last_msg: string;

    @Column()
    last_msg_created_utc: Date;

    @Column()
    num_messages: number;

    @Column()
    num_replies: number;

    @Column()
    seen: boolean;

}

问题:

当尝试对许多消息创建批量插入时,我可以注意到查询没有将外键设置为任何值,而是设置NULL

我尝试插入的消息 json:

{
 id: '1',
 message: 'text',
 receiver: 'someone',
 created_utc: 'utc date...',
 chatRoomId: '123' -> chat room id exists 
}

the query looks like this :
(this query is for single insert not bulk, but it goes the same for bulk)
INSERT INTO "messages"("id", "message", "receiver", "created_utc", "chatRoomId") VALUES ($1, $2, $3, $4, DEFAULT) -- PARAMETERS: [" bJU7","Zdravo test","kompir_zomba","2021-
09-05T09:53:54.693Z"]

这告诉我在插入行时甚至没有考虑 chatRoomId。 该表如下所示

我用来插入消息的 Typeorm 插入查询

@InjectRepository(Message) private messageRepository: Repository<Message>
.....

    this.messageRepository.save(message);

有人知道如何继续吗?

node.js typescript postgresql typeorm
3个回答
7
投票

我在处理 NestJS 项目时也遇到过类似的 TypeORM 问题。

原因:

发生此问题是因为您的

消息实体
(chatRoomId) 中没有定义任何
class Message
字段。因此,当 TypORM 将消息数据与 Message 实体 映射时,它不会设置
chatRoomId

解决方案:

有两种解决方案可以解决此问题。

  1. 您可以在
    chatRoomId
    实体中添加
    Message
    字段,现在您将能够在保存消息数据时发送该字段。

例如

@Column({type: "uuid"}) // <- Assuming that your primary key type is UUID (OR you can have "char")
chatRoomId: string;

现在,通常您不需要为此创建迁移,因为 该字段已存在于数据库表中。

  1. 另一种方法是在保存时将
    ChatRoom
    实体的实例传递给
    message
    对象。

您可以首先使用聊天室的 ID 找到聊天室,然后将其传递到消息对象中。

您的最终

message
对象应如下所示:

{
 id: '1',
 message: 'text',
 receiver: 'someone',
 created_utc: 'utc date...',
 chatRoom: chatRoomData // <-- Assuming that chatRoomData contains the ChatRoom entity
}

0
投票
const test = await this.photosRepository.findOne(data.userId);
    if(!test){
        throw new NotFoundException("Exception message");
    }
    const myPhoto = await this.photosRepository
        .createQueryBuilder()
        .insert()
        .into(Photo)
        .values({
            url: data.url,
            user:{
                id: data.userId
            }

        })
        .execute();

    console.log(myPhoto)

您好,我尝试过这样做,效果很好。 上面例子的表格2我不太明白,你能上传一个例子吗?我是新来的


0
投票

显然在处理

OneToOne
joins
时,TypeORM 会知道该做什么并为你处理。

  @Column("uuid", { name: "parent_id", nullable: true })
  parentId: string;

  @JoinColumn({ name: 'parent_id' }) <-- note the name here
  @OneToOne(() => MoveEntity)
  parent: MoveEntity | null;

ORM 处理关系:ORM 负责管理基于 @OneToOne 注释和外键的移动之间的关系。

可选parentId:您可以灵活地设置parentId以创建层次关系,或将其保留为空以进行没有父级的移动。

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