TypeORM:[364] 错误:在字符 401 处缺少表“userorganisation”的 FROM 子句条目

Posted

技术标签:

【中文标题】TypeORM:[364] 错误:在字符 401 处缺少表“userorganisation”的 FROM 子句条目【英文标题】:TypeORM: [364] ERROR: missing FROM-clause entry for table "userorganisation" at character 401 【发布时间】:2019-02-01 04:48:54 【问题描述】:

在使用TypeORM 并加入我为Postgres 数据库设置的表时,我遇到了一个非常有趣的问题。我想通了,但我想我会在这里为遇到类似问题的其他人发布信息。

我的数据库中设置了 3 个表:userorganisationuser_organisation

这样做的想法是,一个用户可以属于许多组织,名为user_organisation 的表将用户映射到这些组织。所以我的实体看起来像这样,

user.entity.ts

import  TimestampedEntity  from '@shared/entities/timestamped.entity';
import  Organisation  from '@user/entities/organisation.entity';
import  UserOrganisation  from '@user/entities/user-organisation.entity';
import  Column, Entity, Index, JoinTable, ManyToMany, OneToMany, PrimaryGeneratedColumn  from 'typeorm';

@Entity()
@Index(['email', 'password'])
export class User extends TimestampedEntity 
    @PrimaryGeneratedColumn()
    userId: number;

    @Column(
        length: 64
    )
    username: string;

    @Column(
        length: 500
    )
    email: string;

    @Column(
        length: 255
    )
    password: string;

    @Column(
        type: 'json',
    )
    details: any;

    @Column(
        nullable: true
    )
    refreshToken: string;

    @OneToMany(type => UserOrganisation, userOrganisation => userOrganisation.user)
    @JoinTable()
    userOrganisations: UserOrganisation[];

user-organisation.entity.ts

import  Organisation  from '@user/entities/organisation.entity';
import  User  from '@user/entities/user.entity';
import  Column, Entity, JoinColumn, ManyToOne, OneToOne, PrimaryColumn, PrimaryGeneratedColumn  from 'typeorm';

@Entity()
export class UserOrganisation 
    @ManyToOne(type => User, user => user.userOrganisations,  primary: true )
    user: User;

    @ManyToOne(type => Organisation, organisation => organisation.userOrganisations,  primary: true )
    organisation: Organisation;

organisation.entity.ts

import  TimestampedEntity  from '@shared/entities/timestamped.entity';
import  UserOrganisation  from '@user/entities/user-organisation.entity';
import  User  from '@user/entities/user.entity';
import  Column, Entity, JoinColumn, JoinTable, ManyToMany, ManyToOne, OneToMany, OneToOne, PrimaryGeneratedColumn  from 'typeorm';

@Entity()
export class Organisation extends TimestampedEntity 
    @PrimaryGeneratedColumn()
    orgId: number;

    @Column(
        length: 255
    )
    name: string;

    @Column(
        type: 'json'
    )
    details: any;

    @OneToMany(type => UserOrganisation, userOrganisation => userOrganisation.organisation)
    userOrganisations: UserOrganisation[];

然后我试图运行以下查询,

this.userRepository.createQueryBuilder('user')
    .where('user.email = :email',  email )
    .innerJoin(UserOrganisation, 'userOrganisation', 'user.userId = userOrganisation.userUserId')
    .getOne();

这是我收到的错误消息,

ERROR:  missing FROM-clause entry for table "userorganisation" at character 401

最后的查询是这样打印出来的,

SELECT "user"."createdAt" AS "user_createdAt"
 , "user"."updatedAt" AS "user_updatedAt"
 , "user"."userId" AS "user_userId"
 , "user"."username" AS "user_username"
 , "user"."email" AS "user_email"
 , "user"."password" AS "user_password"
 , "user"."details" AS "user_details"
 , "user"."refreshToken" AS "user_refreshToken" 
 FROM "user" "user" 
 INNER JOIN "user_organisation" "userOrganisation" 
      ON      "user"."userId" = userOrganisation.userUserId 
 WHERE "user"."email" = $1

我修复它的方法如下所述。

【问题讨论】:

【参考方案1】:

我在查询中注意到的,

SELECT "user"."createdAt" AS "user_createdAt", "user"."updatedAt" AS "user_updatedAt", "user"."userId" AS "user_userId", "user"."username" AS "user_username", "user"."email" AS "user_email", "user"."password" AS "user_password", "user"."details" AS "user_details", "user"."refreshToken" AS "user_refreshToken" FROM "user" "user" INNER JOIN "user_organisation" "userOrganisation" ON "user"."userId" = userOrganisation.userUserId WHERE "user"."email" = $1

在连接条件中user 表和userOrganisation 表之间是否存在差异,

"user"."userId" = userOrganisation.userUserId

user 表自动用引号括起来,但 userOrganisation 不是...所以我将代码更改为以下内容,

this.userRepository.createQueryBuilder('user')
        .where('user.email = :email',  email )
        .innerJoin(UserOrganisation, 'userOrganisation', '"user"."userId" = "userOrganisation"."userUserId"')
        .getOne();

如果您看上面,我在连接条件中添加了引号。现在一切正常:)

希望这会有所帮助!

【讨论】:

你确定吗?这里我不需要引号,错误来自使用 .where('investors.') 当表的真实名称是 'investor'(单数)【参考方案2】:

干得好。但是,在 typeorm 中使用连接时,您必须按照定义的条件编写条件,然后设置对象。

this.userRepository.createQueryBuilder('user')
        .where('user.email = :email',  email )
        .innerJoin(UserOrganisation, 'userOrganisation', 'user.userId=userOrganisation.user.userId')
        .getOne();

这样就不用加引号了。

生成的 sql 不显示引号,因为它不知道如何填充条件。

我希望这会有所帮助。

【讨论】:

以上是关于TypeORM:[364] 错误:在字符 401 处缺少表“userorganisation”的 FROM 子句条目的主要内容,如果未能解决你的问题,请参考以下文章

如何在 NestJs 中捕获 Typeorm 事务错误

使用 TypeORM 在“订单子句”中获取错误“未知列”

PostgreSQL 与 TypeORM 错误“在 \"Sep\" 处或附近出现语法错误”

错误:使用 Nestjs + Graphql + Typeorm 时无法确定 GraphQL 输入类型

未捕获的错误:找不到模块“typeorm”

如何修复预期值:“1”接收到的数组:[“COUNT (*)”:“1”] 在带有 jest 框架的 TypeORM 中出现错误