typescript - Nume de alias duplicate pentru câmpuri diferite


Folosesc typeorm v 0.1.14.

Se pare că typeorm generează același nume de alias pentru două coloane diferite într-o asociere Many-to-One. Nu contează dacă folosesc încărcarea eager în decoratorul @ManyToOne (care încarcă copilul folosind metoda .find() pe repository, de exemplu) sau dacă folosesc funcționalitatea query builder pentru a încărca relația.

Cel mai simplu exemplu pe care l-am putut recrea cu asta este mai jos.

// SampleStatus entity/file:
import { Entity, Column, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';

@Entity({name: 'statuses', schema: 'master'})
export class SampleStatus {

    @PrimaryGeneratedColumn()
    public id: number;
}

// Sample entity that has a child statusimport { Entity, Column, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
import { SampleStatus } from './sample-status.entity';

@Entity({ name: 'samples', schema: 'master'})
export class Sample {

    @PrimaryGeneratedColumn()
    public id: number;

    @Column()
    public name: string;

    @ManyToOne(type => SampleStatus, status => status.id, { eager: true })
    public status: SampleStatus;
}

Folosind acele entități de mai sus în cel mai simplu mod posibil: let result: Sample[] | null=await getRepository(Sample).find() || [];

Acest lucru generează următoarea interogare înregistrată, formatată de mine:

SELECT "Sample"."id" AS "Sample_id", 
  "Sample"."name" AS "Sample_name", 
  "Sample"."status_id" AS "Sample_status_id", 
  "Sample_status"."id" AS "Sample_status_id" 
FROM "master"."samples" "Sample" 
  LEFT JOIN "master"."statuses" "Sample_status" 
    ON "Sample_status"."id"="Sample"."status_id"

Observați cum sunt generate cele două nume -- ambele sunt același nume de coloană cu alias.

Folosesc acest fragment de cod pe care l-am găsit, care convertește numele proprietăților entității pentru a fi scrise în snake_case. Acesta este transmis în configurarea conexiunii.

import { DefaultNamingStrategy, NamingStrategyInterface } from "typeorm";
import { snakeCase } from 'typeorm/util/StringUtils'

export class SnakeCaseNamingStrategy extends DefaultNamingStrategy  {

    tableName(targetName: string, userSpecifiedName: string): string {
        return userSpecifiedName ? userSpecifiedName : snakeCase(targetName);
    }

    columnName(propertyName: string, customName: string, embeddedPrefixes: string[]): string {
        return snakeCase(embeddedPrefixes.concat(customName ? customName : propertyName).join("_"));
    }

    columnNameCustomized(customName: string): string {
        return customName;
    }

    relationName(propertyName: string): string {
        return snakeCase(propertyName);
    }

    joinTableName(firstTableName: string, secondTableName: string, firstPropertyName: string, secondPropertyName: string): string {
        return `${snakeCase(firstTableName)}_${secondTableName}`;
    }
}

Deși valoarea care este preluată este aceeași (deoarece este o coloană de îmbinare) și nu cauzează cu adevărat o problemă la rulare, am observat acest lucru când am luat interogarea înregistrată și am transformat-o într-o vedere. Postgres s-a plâns de numele coloanei duplicat.

Există o modalitate de a da celui de-al doilea select un alias cu un nume diferit, sau poate să nu selectăm deloc a doua valoare?

Răspuns #1

Aceasta este o problemă cunoscută a TypeORM pentru bazele de date care folosesc strategia de denumire snake case, care se pare că va fi rezolvată în versiunea lor 0.3.0 (vezi acest fir: https://github.com/typeorm/typeorm/issues/2200)

Deocamdată, poți să eviți această problemă definindu-ți strategia de denumire astfel:

const SnakeNamingStrategy = require('typeorm-naming-strategies').SnakeNamingStrategy;

module.exports = {
   type: ...,
   host: ...,
   port: ...,
   ...
   namingStrategy: new SnakeNamingStrategy(),
}

Care este puțin mai plăcut de lucrat decât soluția ta actuală

Răspunsul #2