Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeORM does not create tables, columns etc

Tags:

typeorm

I have set up a system with typeorm (https://github.com/typeorm/typeorm) and NestJs (https://github.com/nestjs/nest), but TypeORM isn't creating the tables or columns. My setup is like this:

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
    ]
  })

And the entities are:

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

@Entity()
export class UserPassword {

  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  hash: string;

  @Column()
  algorithm: string;

}

and

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;

}

Then I try to create a user like this:

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

But I get the following error:

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

When I insert the table manually then I get the error:

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

So it seems like TypeORM doesn't generate the tables / columns. Does anyone know why this could be?

like image 933
bersling Avatar asked Oct 20 '17 06:10

bersling


2 Answers

Even though the previous answers are acceptable for development environment, they are wrong for production.

What you are looking for are migrations. Migrations are executed when connection is established and are recorded - no migration will run more than once. TypeORM also provides CLI which allows you to generate migrations (read more here), making it much faster to create them. TypeORM also marks each migration with a timestamp prefix, ensuring they will run in proper sequence - sometimes you might want to run migrations in primary tables first, sometimes on supporting tables. When configuring connection, you load migrations like this:

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
})

Migrations are built composed of 2 parts - up (migration code) and down (code to revert migration). Simple example:

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'
        );
    }
}

If you want to read more, TypeORM has detailed description on their official Git repository here

In general, it is not good to leave the synchronization of the data and schema to the framework. It is something that should be done by you to ensure the database schema will be preserved. The CLI I linked before also allows you to run migrations and therefore test them before pushing changes to production.

like image 145
Jiri Kralovec Avatar answered Sep 18 '22 07:09

Jiri Kralovec


Connection has ‘synchronize()’ method. You can use it to create tables and columns automatically:

const connection = await createConnection(...);
await connection.synchronize();
like image 43
Bogdan Surai Avatar answered Sep 18 '22 07:09

Bogdan Surai