web-dev-qa-db-fra.com

TypeORM ne crée pas de tables, de colonnes, etc.

J'ai mis en place un système avec typeorm ( https://github.com/typeorm/typeorm ) et NEST ( https://github.com/nestjs/nest ) , mais TypeORM ne crée pas les tables ou les colonnes. Ma configuration est la suivante:

import {UserPassword} from '../user/user-password.entity';
import {User} from '../user/user.entity';

createConnection({
    type: 'mysql',
    Host: 'typeorm2.cn32tstd6wqk.eu-central-1.rds.amazonaws.com',
    port: 1234,
    username: 'username',
    password: 'password',
    database: 'dbname',
    entities: [
      // __dirname + '/../**/*.entity{.ts,.js}'
      UserPassword,
      User
    ]
  })

Et les entités sont:

import {Entity, Column, PrimaryGeneratedColumn, OneToOne, JoinColumn} from 'typeorm';

@Entity()
export class UserPassword {

  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  hash: string;

  @Column()
  algorithm: string;

}

et

import {Entity, Column, PrimaryGeneratedColumn, OneToOne, JoinColumn} from 'typeorm';
import {UserPassword} from './user-password.entity';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 35 })
  firstName: string;

  @Column({ length: 35 })
  lastName: string;

  @Column({ length: 50})
  mail: string;

  @OneToOne(type => UserPassword)
  @JoinColumn()
  password: UserPassword;

}

Ensuite, j'essaie de créer un utilisateur comme celui-ci:

// ... some code
await this.userPasswordRepository.save(userPassword);
return await this.userRepository.save(user);

Mais j'obtiens l'erreur suivante:

QueryFailedError: ER_NO_SUCH_TABLE: Table 'typeorm2.user_password' doesn't exist

Lorsque j'insère la table manuellement, j'obtiens l'erreur:

QueryFailedError: ER_BAD_FIELD_ERROR: Unknown column 'hash' in 'field list'

Il semble donc que typeorm ne génère pas les tables/colonnes. Est-ce que quelqu'un sait pourquoi cela pourrait être?

8
bersling

La connexion a la méthode "synchronize ()". Vous pouvez l'utiliser pour créer automatiquement des tableaux et des colonnes:

const connection = await createConnection(...);
await connection.synchronize();
12
Bogdan Surai

En ajoutant ce qui suit à ormconfig.json/js/xml/etc:

synchronize: true  

Il crée la table une fois s'il n'existe pas.

3
wallena3

Même si les réponses précédentes sont acceptables pour l'environnement de développement , elles sont incorrectes pour la production .

Ce que vous recherchez, ce sont des migrations. Les migrations sont exécutées lorsque la connexion est établie et sont enregistrées - aucune migration ne s'exécutera plus d'une fois. TypeORM fournit également une CLI qui vous permet de générer des migrations ( lire la suite ici ), ce qui rend leur création beaucoup plus rapide. TypeORM marque également chaque migration avec un préfixe d'horodatage, garantissant qu'elles s'exécuteront dans le bon ordre - parfois, vous souhaiterez peut-être d'abord exécuter les migrations dans les tables principales, parfois sur les tables de prise en charge. Lors de la configuration de la connexion, vous chargez des migrations comme ceci:

createConnection({
    type: 'mysql',
    Host: 'typeorm2.cn32tstd6wqk.eu-central-1.rds.amazonaws.com',
    port: 1234,
    username: 'username',
    password: 'password',
    database: 'dbname',
    entities: [
      // __dirname + '/../**/*.entity{.ts,.js}'
      UserPassword,
      User
    ],
    migrations: ['./migrations/*.js'],
    synchronize: false
  })

Les migrations sont construites en 2 parties - vers le haut (code de migration) et vers le bas (code pour annuler la migration). Exemple simple:

import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddImageToUser implements MigrationInterface {

  async up(queryRunner: QueryRunner): Promise<any> {
    await queryRunner.query(
       'ALTER TABLE "user" ADD image varchar(255)'
    );
  }
  async down(queryRunner: QueryRunner): Promise<any> {
    await queryRunner.query(
       'ALTER TABLE "user" DROP COLUMN image'
    );
  }

}

Si vous voulez en savoir plus, TypeORM a une description détaillée de leur dépôt Git officiel ici

En général, il n'est pas bon de laisser la synchronisation des données et du schéma au framework. C'est quelque chose que vous devez faire pour vous assurer que le schéma de la base de données sera préservé. L'interface CLI que j'ai liée auparavant vous permet également d'exécuter des migrations et donc de les tester avant de pousser les modifications en production.

2
Jiri Kralovec

Je suis passé à la version typeorm .1.0-alpha.4 qui a l'option autoSchemaSync lors de la création d'une connexion, ce qui l'a fait fonctionner:

createConnection({
  type: 'mysql',
  Host: 'typeorm2.cn32tstd6wqk.eu-central-1.rds.amazonaws.com',
  port: 1234,
  username: 'username',
  password: 'password',
  database: 'dbname',
  entities: [
    // __dirname + '/../**/*.entity{.ts,.js}'
    UserPassword,
    User
  ],
  autoSchemaSync: true,
})
2
bersling

Pour moi, le problème était que l'entité pour laquelle je voulais générer la migration n'était pas une classe exportée.

0
pbn

Ce qui m'a aidé, c'est d'ajouter le nom du modèle au décorateur "Entity ()":

@Entity({ name: 'User' })
0
Jose Miguel Ochoa