【问题标题】:TypeORM: QueryFailedError: relation does not existTypeORM:QueryFailedError:关系不存在
【发布时间】:2021-06-28 18:27:52
【问题描述】:

我需要一些关于迁移的帮助。我正在尝试使用迁移来播种数据库。但我收到错误“QueryFailedError:关系“帐户”不存在”。我认为这只是典型的新手错误。所以请检查我的代码:

account.entity.ts

import { BeforeInsert, Column, Entity, OneToMany } from 'typeorm';
import { AbstractEntity } from '../../common/abstract.entity';
import { SourceEntity } from '../source/source.entity';
import { UtilsService } from '../../shared/services/utils.service';

@Entity({ name: 'account' })
export class AccountEntity extends AbstractEntity {
  @Column({ unique: true })
  username: string;

  @Column({ nullable: true })
  password: string;

  @OneToMany(() => SourceEntity, (source) => source.account, {
    cascade: true,
  })
  sources: SourceEntity[];

  @BeforeInsert()
  async setPassword() {
    this.password = UtilsService.generateHash(this.password);
  }
}

seed-data.migration.ts

import { getCustomRepository, MigrationInterface, QueryRunner } from 'typeorm';
import { AccountRepository } from '../modules/account/account.repository';
import { SourceRepository } from '../modules/source/source.repository';

type DataType = {
  username: string;
  password: string;
  sources: { username: string }[];
};

export class SeedData1617243952346 implements MigrationInterface {
  private data: DataType[] = [
    {
      username: 'test',
      password: 'password',
      sources: [
        { username: 'some_test' },
        { username: 'okey_test' },
        { username: 'super_test' },
      ],
    },
    {
      username: 'account',
      password: 'password',
      sources: [
        { username: 'some_account' },
        { username: 'okey_account' },
        { username: 'super_account' },
      ],
    },
  ];

  public async up(): Promise<void> {
    await Promise.all(
      this.data.map(async (item) => {
        const accountRepository = getCustomRepository(AccountRepository);
        const accountEntity = accountRepository.create();
        accountEntity.username = item.username;
        accountEntity.password = item.password;

        const sourceRepository = getCustomRepository(SourceRepository);
        const sources = [];

        await Promise.all(
          item.sources.map(async (sourceItem) => {
            const sourceEntity = sourceRepository.create();
            sourceEntity.username = sourceItem.username;

            sources.push(sourceEntity);
          }),
        );

        accountEntity.sources = sources;
        const account = await accountRepository.save(accountEntity);
        console.log('Account created:', account.id);
      }),
    );
  }

  public async down(): Promise<void> {
    await Promise.all(
      this.data.map(async (item) => {
        const sourceRepository = getCustomRepository(SourceRepository);
        const accountRepository = getCustomRepository(AccountRepository);

        const account = await accountRepository.findOne({
          where: { username: item.username },
        });
        if (account) {
          await Promise.all(
            item.sources.map(async (src) => {
              const source = await sourceRepository.findOne({
                where: { username: src.username },
              });
              if (source) {
                await sourceRepository.delete(source);
              }
            }),
          );

          await accountRepository.delete(account);
        }
      }),
    );
  }
}

source.entity.ts

import { Column, Entity, ManyToOne } from 'typeorm';
import { AbstractEntity } from '../../common/abstract.entity';
import { AccountEntity } from '../account/account.entity';

@Entity({ name: 'source' })
export class SourceEntity extends AbstractEntity {
  @Column({ unique: true })
  username: string;

  @Column({ default: true })
  overrideCaption: boolean;

  @ManyToOne(() => AccountEntity, (account) => account.sources)
  account: AccountEntity;
}

错误:

Error during migration run:
QueryFailedError: relation "account" does not exist
    at new QueryFailedError (/home/wiha/dev/own/instahub/src/error/QueryFailedError.ts:9:9)
    at PostgresQueryRunner.<anonymous> (/home/wiha/dev/own/instahub/src/driver/postgres/PostgresQueryRunner.ts:228:19)
    at step (/home/wiha/dev/own/instahub/node_modules/tslib/tslib.js:143:27)
    at Object.throw (/home/wiha/dev/own/instahub/node_modules/tslib/tslib.js:124:57)
    at rejected (/home/wiha/dev/own/instahub/node_modules/tslib/tslib.js:115:69)
    at processTicksAndRejections (internal/process/task_queues.js:97:5) {
  length: 106,
  severity: 'ERROR',
  code: '42P01',
  detail: undefined,
  hint: undefined,
  position: '13',
  internalPosition: undefined,
  internalQuery: undefined,
  where: undefined,
  schema: undefined,
  table: undefined,
  column: undefined,
  dataType: undefined,
  constraint: undefined,
  file: 'parse_relation.c',
  line: '1191',
  routine: 'parserOpenTable',
  query: 'INSERT INTO "account"("id", "created_at", "updated_at", "username", "password") VALUES (DEFAULT, DEFAULT, DEFAULT, $1, $2) RETURNING "id", "created_at", "updated_at"',
  parameters: [
    'test',
    '$2b$10$iB6yb3D8e6iGmKoVAJ7eYeYfoItclw5lcVXqauPf9VH94DlDrbuSa'
  ]
}

表是在另一个迁移中创建的

数据库:PostgreSQL 12.6
节点:14.0.0
类型ORM:0.2.32
@nestjs/typeorm:7.1.5

【问题讨论】:

  • 你如何初始化你的数据库?
  • @shusson 通过 TypeOrmModule.forRootAsync
  • 你能显示更多代码吗? TypeORM 可以为您创建架构,但这取决于您如何初始化 TypeORM 连接。
  • @shusson 检查此gist
  • 您需要仔细检查您的实体列表是否包含帐户实体。 gist.github.com/qWici/…

标签: typeorm


【解决方案1】:

我收到此错误是因为我在值周围使用了双引号而不是单引号。例如:

错误:

private static async getProducts(): Promise<Product[]> {
  return await getRepository(Product)
    .createQueryBuilder('product')
    .where('product.source = "noobie"') // <---- DOUBLE QUOTES = BAD!!!
    .getMany();
}

右:

private static async getProducts(): Promise<Product[]> {
  return await getRepository(Product)
    .createQueryBuilder('product')
    .where("product.source = 'noobie'") // <---- SINGLE QUOTES!!!
    .getMany();
}

【讨论】:

    【解决方案2】:

    我正在尝试类似的东西。我将数据源 [国家] 放在一个 JSON 文件中,这对我有用: `

    // In a prev migration the countries table was created
    // Then in a new migration
    
    export class SeedCountriesTable1616610473154 implements MigrationInterface {
        public async up(queryRunner: QueryRunner): Promise<void> {
            // Trying to commit last transcaction
            await queryRunner.commitTransaction().then(async () => {
                // Seeding database
                // Then try to start another one
                await queryRunner.startTransaction().then(async () => {
                    await getRepository('countries').save(countries);
                });
            });
        }
    
        // eslint-disable-next-line @typescript-eslint/no-empty-function
        public async down(): Promise<void> {}
    }
    

    ` 希望能帮到你。

    【讨论】:

    • 干得好,这正是我们需要的!
    【解决方案3】:

    通过 TypeORM 创建连接时,如果您希望 TypeORM 为您创建架构,则需要传递 synchronize: true,。或者,您可以使用带有 schema:sync 命令的 CLI 手动运行同步。

    更多 例如:

    
    createConnection({
        type: "mysql",
        host: "localhost",
        port: 3306,
        username: "root",
        password: "admin",
        database: "test",
        entities: [
            Photo
        ],
    
    // ---
        synchronize: true,
    // ---
        logging: false
    

    来自docs

    synchronize - 指示是否应在每次应用程序启动时自动创建数据库模式。请小心使用此选项,不要在生产中使用它 - 否则您可能会丢失生产数据。此选项在调试和开发期间很有用。作为替代方案,您可以使用 CLI 并运行 schema:sync 命令。请注意,对于 MongoDB 数据库,它不会创建模式,因为 MongoDB 是无模式的。相反,它只是通过创建索引来同步。

    【讨论】:

    • 将此答案标记为正确。但我实际上做了什么: 1. 删除为实体创建表的迁移 2. 将 synchronize 设置为 true 3. 重新创建数据库 4. 运行 typeorm schema:sync 5. 运行迁移
    猜你喜欢
    • 2013-05-21
    • 2017-04-20
    • 2022-01-22
    • 2021-03-30
    • 2017-04-22
    • 2017-10-19
    • 2017-07-05
    • 2023-04-03
    • 1970-01-01
    相关资源
    最近更新 更多