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ă
