question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Table indexes needlessly recreated when generating migrations

See original GitHub issue

Issue type:

[ ] question [x ] bug report [ ] feature request [ ] documentation issue

Database system/driver:

[ ] cordova [ ] mongodb [ ] mssql [ x] mysql / mariadb (using mysql 8) [ ] oracle [ ] postgres [ ] cockroachdb [ ] sqlite [ ] sqljs [ ] react-native [ ] expo

TypeORM version:

[ ] latest [ ] @next [x ] 0.2.19

Steps to reproduce or a small repository showing the problem:

  1. Create models below
  2. Generate and run a migration (generated code shown below).
  3. Make no changes to the models
  4. Generate another migration (generated code shown below)

Results: Migration drops and recreates many indexes

Expected: No changes in the migration since the model has not changed

Note that the only change in the migration seems to be from the index name REL_36c1bea209538ff07049dd748a in the initial creation of the table to IDX_36c1bea209538ff07049dd748a in the migration.

Models

@Entity({ name: 'users2' })
export class Users {
  @PrimaryGeneratedColumn()
  id!: string;
}

@Entity({ name: 'simple_example' })
@Unique(['userId', 'choice'])
export class SimpleExample {

  @PrimaryGeneratedColumn()
  id!: string;

  @Column({ name: 'user_id', nullable: false })
  userId!: UserID;

  @Column({ name: 'choice', nullable: false })
  choice!: number;

  @OneToOne(() => Users)
  @JoinColumn({ name: ReferralSurvey.columnNames.userId })
  user!: UserModel;
}

Initial migration

import {MigrationInterface, QueryRunner} from "typeorm";

export class createExample1574282003669 implements MigrationInterface {

    public async up(queryRunner: QueryRunner): Promise<any> {
        await queryRunner.query("CREATE TABLE `users2` (`id` int NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`)) ENGINE=InnoDB", undefined);
        await queryRunner.query("CREATE TABLE `simple_example` (`id` int NOT NULL AUTO_INCREMENT, `user_id` int NOT NULL, `choice` int NOT NULL, UNIQUE INDEX `IDX_a1ebc46dd9a46cf638f43239fe` (`user_id`, `choice`), UNIQUE INDEX `REL_36c1bea209538ff07049dd748a` (`user_id`), PRIMARY KEY (`id`)) ENGINE=InnoDB", undefined);
        await queryRunner.query("ALTER TABLE `simple_example` ADD CONSTRAINT `FK_36c1bea209538ff07049dd748ad` FOREIGN KEY (`user_id`) REFERENCES `users2`(`id`) ON DELETE NO ACTION ON UPDATE NO ACTION", undefined);
    }

    public async down(queryRunner: QueryRunner): Promise<any> {
        await queryRunner.query("ALTER TABLE `simple_example` DROP FOREIGN KEY `FK_36c1bea209538ff07049dd748ad`", undefined);
        await queryRunner.query("DROP INDEX `REL_36c1bea209538ff07049dd748a` ON `simple_example`", undefined);
        await queryRunner.query("DROP INDEX `IDX_a1ebc46dd9a46cf638f43239fe` ON `simple_example`", undefined);
        await queryRunner.query("DROP TABLE `simple_example`", undefined);
        await queryRunner.query("DROP TABLE `users2`", undefined);
    }
}

Second migration with no changes to the model

import {MigrationInterface, QueryRunner} from "typeorm";

export class generateAfterNoChanges1574282199014 implements MigrationInterface {

    public async up(queryRunner: QueryRunner): Promise<any> {
        await queryRunner.query("ALTER TABLE `simple_example` DROP FOREIGN KEY `FK_36c1bea209538ff07049dd748ad`", undefined);
        await queryRunner.query("DROP INDEX `IDX_a1ebc46dd9a46cf638f43239fe` ON `simple_example`", undefined);
        await queryRunner.query("ALTER TABLE `simple_example` ADD UNIQUE INDEX `IDX_36c1bea209538ff07049dd748a` (`user_id`)", undefined);
        await queryRunner.query("CREATE UNIQUE INDEX `IDX_a1ebc46dd9a46cf638f43239fe` ON `simple_example` (`user_id`, `choice`)", undefined);
        await queryRunner.query("ALTER TABLE `simple_example` ADD CONSTRAINT `FK_36c1bea209538ff07049dd748ad` FOREIGN KEY (`user_id`) REFERENCES `users2`(`id`) ON DELETE NO ACTION ON UPDATE NO ACTION", undefined);
    }

    public async down(queryRunner: QueryRunner): Promise<any> {
        await queryRunner.query("ALTER TABLE `simple_example` DROP FOREIGN KEY `FK_36c1bea209538ff07049dd748ad`", undefined);
        await queryRunner.query("DROP INDEX `IDX_a1ebc46dd9a46cf638f43239fe` ON `simple_example`", undefined);
        await queryRunner.query("ALTER TABLE `simple_example` DROP INDEX `IDX_36c1bea209538ff07049dd748a`", undefined);
        await queryRunner.query("CREATE UNIQUE INDEX `IDX_a1ebc46dd9a46cf638f43239fe` ON `simple_example` (`user_id`, `choice`)", undefined);
        await queryRunner.query("ALTER TABLE `simple_example` ADD CONSTRAINT `FK_36c1bea209538ff07049dd748ad` FOREIGN KEY (`user_id`) REFERENCES `users2`(`id`) ON DELETE NO ACTION ON UPDATE NO ACTION", undefined);
    }
}

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:12
  • Comments:9

github_iconTop GitHub Comments

2reactions
noneedinmagiccommented, Jan 15, 2020

Try default: () => 'NULL' in column config.

@noneedinmagic Where would this need to go to fix the issue?

In column config. Like

@Column({
  name: 'optional_column',
  default: () => 'NULL',
})
optionalColumn: string;
0reactions
zorjicommented, Apr 7, 2022

I am still able to reproduce this issue in 0.3.4

Read more comments on GitHub >

github_iconTop Results From Across the Web

Optimize index maintenance to improve query performance ...
Creating a clustered index on a table, including recreating the clustered index with a different key using CREATE CLUSTERED INDEX .
Read more >
Migrate index messes up columns of index — oracle-tech
Hi I'm migrate from MS SQL 2005 to Oracle 11g using SQL Developer V3.0.04 and using the batch file migration.bat. Everything worked fine....
Read more >
sql server 2008 r2 - Recreate Indexes on 1 billion record table
Now, the best way to answer this is to set up a smaller test database of a few gigabytes. It will accurately predict...
Read more >
An Introduction to Fillfactor in SQL Server
“Fillfactor” is a setting for indexes in SQL Server. When you create or rebuild an index, you can tell SQL Server what percentage...
Read more >
Rails migration file to create table and add unique index on ...
Rollback the migration for CreateSignups . This will drop the current table and then doing rake db:migrate will re-create the table with indexes...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found