简体   繁体   中英

How can I get values from a TypeORM property decorator

import { PrimaryColumn, Column } from 'typeorm';

export class LocationStatus {
  @PrimaryColumn({ name: 'location_id' })
  locationId: string;

  @Column({ name: 'area_code', type: 'int' })
  areaCode: number;
}

I spent the past few hours trying to figure it out how to retrieve a name property value location_id and area_code from a property decorator @Column() , but no luck. I'm not sure whether it's even possible to get a list of properties or not.

Judging from the typeorm source code (here: 1 , 2 , 3 , 4 ) you can access all kinds of stuff through global variable typeormMetadataArgsStorage (like window.typeormMetadataArgsStorage or global.typeormMetadataArgsStorage ). Explore it, and I believe you'll find what you're seeking for with something like that:

const global_context = ??? // depends on your environment
const property_to_look_for = `areaCode`
const name = global_context.typeormMetadataArgsStorage
  .columns
  .filter(col => col.propertyName === property_to_look_for && col.target === LocationStatus)
  .options
  .name
console.log(name)

UPDATED

For those of you who are currently using Nest like myself, here's what I've done so far.


import { getMetadataArgsStorage, InsertResult } from 'typeorm';

export class PinLocationStatusRepository extends Repository<PinLocationStatus> {
  // Column names in this array, the value should not be modified.
  // For instance, the location_id value "location_ko_01" won't be changed.
  private static immutableColumnNames = ['location_id', ...]; 

  private static mutableColumnFound(name: string): boolean {
    return PinLocationStatusRepository.immutableColumnNames.every(colName => colName !== name);
  }

  savePinLocation(state: PinLocationStatus): Promise<InsertResult> {
    const columns = getMetadataArgsStorage()
     .columns.filter(({ target }) => target === PinLocationStatus)
     .map(({ options, propertyName }) => (!options.name ? propertyName : options.name))
     .reduce((columns, name) => {
       if (PinLocationStatusRepository.mutableColumnFound(name)) {
         columns.push(name);
       }
       return columns;
    }, []);

    return this.createQueryBuilder()
      .insert()
      .into(PinLocationStatus)
      .values(state)
      .orUpdate({ overwrite: columns }) // ['area_code']
      .execute();
  }
}
  1. Extract the column name from the @Column() decorator.
  2. Filter out some column names where the values have to remain the same.
  3. Pass the columns variable into overwrite property.

You will get a correct result unless the area_code is an immutable column.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM