Bird
Raised Fist0
NestJSframework~20 mins

Migrations in NestJS - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Migration Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ component_behavior
intermediate
2:00remaining
What is the output of this migration script execution?

Consider a NestJS migration that adds a new column to an existing table. What will be the state of the database after running this migration?

NestJS
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddAgeColumn1680000000000 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`ALTER TABLE users ADD COLUMN age int`);
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`ALTER TABLE users DROP COLUMN age`);
  }
}
AThe 'users' table will have a new column named 'age' of type integer.
BThe migration will fail because 'ALTER TABLE' is not supported in migrations.
CThe 'users' table will be deleted and recreated with the 'age' column.
DNo changes will be made to the database because the migration script is empty.
Attempts:
2 left
💡 Hint

Think about what the up method does in a migration.

📝 Syntax
intermediate
2:00remaining
Which option contains a syntax error in a NestJS migration?

Identify the migration code snippet that will cause a syntax error when executed.

Aawait queryRunner.query(`ALTER TABLE users ADD age int`);
Bawait queryRunner.query('ALTER TABLE users DROP COLUMN age');
Cawait queryRunner.query(`ALTER TABLE users ADD COLUMN created_at timestamp`);
Dawait queryRunner.query(`ALTER TABLE users ADD COLUMN email varchar(255)`);
Attempts:
2 left
💡 Hint

Check the SQL syntax for adding a column.

🔧 Debug
advanced
2:00remaining
Why does this migration fail to rollback properly?

Given the migration below, why does running the down method cause an error?

NestJS
import { MigrationInterface, QueryRunner } from 'typeorm';

export class RenameUsernameToUser1680000000001 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`ALTER TABLE users RENAME COLUMN username TO user`);
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`ALTER TABLE users RENAME COLUMN user TO username`);
  }
}
AThe down method should drop the 'user' column instead of renaming.
BThe migration fails because 'RENAME COLUMN' is not supported in SQL.
CThe down method tries to rename 'username' to 'user' again, but 'username' no longer exists after up migration.
DThe migration fails because the table 'users' does not exist.
Attempts:
2 left
💡 Hint

Think about the state of the database after the up method runs.

❓ state_output
advanced
2:00remaining
What is the state of the database after running this migration?

This migration creates a new table. What will the database contain after running up?

NestJS
import { MigrationInterface, QueryRunner } from 'typeorm';

export class CreateProductsTable1680000000002 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`CREATE TABLE products (id int PRIMARY KEY, name varchar(100), price decimal)`);
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`DROP TABLE products`);
  }
}
AThe migration will create a table named 'product' (singular) instead of 'products'.
BThe migration will fail because 'decimal' is not a valid column type.
CThe 'products' table will be created but without any columns.
DThe database will have a new table named 'products' with columns 'id', 'name', and 'price'.
Attempts:
2 left
💡 Hint

Check the SQL syntax for creating tables and column definitions.

🧠 Conceptual
expert
2:00remaining
Which option best describes the purpose of the 'down' method in NestJS migrations?

Why is the down method important in a migration class?

AIt runs automatically before the <code>up</code> method to prepare the database.
BIt defines how to revert the changes made by the <code>up</code> method, allowing rollback of the migration.
CIt is used to seed initial data into the database after migration.
DIt validates the migration syntax before execution.
Attempts:
2 left
💡 Hint

Think about what happens if you want to undo a migration.

Practice

(1/5)
1. What is the main purpose of migrations in a NestJS project using TypeORM?
easy
A. To handle HTTP requests and responses
B. To safely update the database schema step-by-step
C. To write business logic for the application
D. To manage user authentication

Solution

  1. Step 1: Understand what migrations do

    Migrations help change the database structure safely without losing data.
  2. Step 2: Identify the correct purpose in NestJS context

    They are not for business logic or HTTP handling but for database schema updates.
  3. Final Answer:

    To safely update the database schema step-by-step -> Option B
  4. Quick Check:

    Migrations = safe database updates [OK]
Hint: Migrations change database structure safely [OK]
Common Mistakes:
  • Confusing migrations with business logic
  • Thinking migrations handle HTTP requests
  • Assuming migrations manage authentication
2. Which command correctly runs all pending migrations in a NestJS project using TypeORM?
easy
A. npx typeorm migration:create
B. npx typeorm migration:revert
C. npx typeorm migration:generate
D. npx typeorm migration:run

Solution

  1. Step 1: Recall commands for migrations

    migration:run applies pending migrations to the database.
  2. Step 2: Differentiate from other commands

    migration:create creates a new migration file, migration:generate generates migration from schema changes, and migration:revert undoes the last migration.
  3. Final Answer:

    npx typeorm migration:run -> Option D
  4. Quick Check:

    Run migrations = migration:run [OK]
Hint: Run migrations with migration:run command [OK]
Common Mistakes:
  • Using migration:create to run migrations
  • Confusing migration:generate with migration:run
  • Using migration:revert to apply migrations
3. Given this migration class, what will happen when up() is run?
export class AddAgeColumn1678901234567 {
  async up(queryRunner) {
    await queryRunner.query(`ALTER TABLE users ADD COLUMN age int`);
  }
  async down(queryRunner) {
    await queryRunner.query(`ALTER TABLE users DROP COLUMN age`);
  }
}
medium
A. Creates a new table called 'age'
B. Removes the 'age' column from the 'users' table
C. Adds a new integer column 'age' to the 'users' table
D. Throws a syntax error because of missing semicolons

Solution

  1. Step 1: Analyze the up() method

    The up() method runs SQL to add a column named 'age' of type integer to the 'users' table.
  2. Step 2: Understand the effect of the query

    This modifies the existing 'users' table by adding the new column; it does not remove columns or create new tables.
  3. Final Answer:

    Adds a new integer column 'age' to the 'users' table -> Option C
  4. Quick Check:

    up() adds column 'age' [OK]
Hint: up() applies changes like adding columns [OK]
Common Mistakes:
  • Confusing up() with down() method
  • Thinking it creates a new table
  • Assuming syntax error due to semicolons
4. You wrote this migration but get an error when running npx typeorm migration:run. What is the likely problem?
export class RemoveEmailColumn1678901234568 {
  async up(queryRunner) {
    await queryRunner.query(`ALTER TABLE users DROP email`);
  }
  async down(queryRunner) {
    await queryRunner.query(`ALTER TABLE users ADD email varchar(255)`);
  }
}
medium
A. The SQL syntax for dropping a column is incorrect
B. The migration class name is invalid
C. Missing async keyword in down() method
D. The migration file is not saved

Solution

  1. Step 1: Check the SQL in up() method

    The query ALTER TABLE users DROP email is incorrect SQL syntax for dropping a column.
  2. Step 2: Correct SQL syntax for dropping a column

    The correct syntax is ALTER TABLE users DROP COLUMN email. Missing 'COLUMN' causes the error.
  3. Final Answer:

    The SQL syntax for dropping a column is incorrect -> Option A
  4. Quick Check:

    DROP COLUMN keyword required in SQL [OK]
Hint: Use DROP COLUMN to remove columns in SQL [OK]
Common Mistakes:
  • Omitting COLUMN keyword in DROP statement
  • Assuming class name causes error
  • Forgetting async keyword (not the cause here)
5. You want to create a migration that renames a column 'username' to 'user_name' in the 'accounts' table and can be reverted. Which up() and down() methods are correct?
hard
A.
async up(queryRunner) {
  await queryRunner.query(`ALTER TABLE accounts RENAME COLUMN username TO user_name`);
}
async down(queryRunner) {
  await queryRunner.query(`ALTER TABLE accounts RENAME COLUMN user_name TO username`);
}
B.
async up(queryRunner) {
  await queryRunner.query(`ALTER TABLE accounts CHANGE username user_name varchar(255)`);
}
async down(queryRunner) {
  await queryRunner.query(`ALTER TABLE accounts CHANGE user_name username varchar(255)`);
}
C.
async up(queryRunner) {
  await queryRunner.query(`ALTER TABLE accounts DROP COLUMN username`);
  await queryRunner.query(`ALTER TABLE accounts ADD COLUMN user_name varchar(255)`);
}
async down(queryRunner) {
  await queryRunner.query(`ALTER TABLE accounts DROP COLUMN user_name`);
  await queryRunner.query(`ALTER TABLE accounts ADD COLUMN username varchar(255)`);
}
D.
async up(queryRunner) {
  await queryRunner.query(`RENAME COLUMN username TO user_name`);
}
async down(queryRunner) {
  await queryRunner.query(`RENAME COLUMN user_name TO username`);
}

Solution

  1. Step 1: Identify correct SQL syntax for renaming columns

    The standard SQL syntax supported by many databases is ALTER TABLE table_name RENAME COLUMN old_name TO new_name.
  2. Step 2: Check each option's SQL correctness and revert logic

    async up(queryRunner) {
      await queryRunner.query(`ALTER TABLE accounts RENAME COLUMN username TO user_name`);
    }
    async down(queryRunner) {
      await queryRunner.query(`ALTER TABLE accounts RENAME COLUMN user_name TO username`);
    }
    uses correct syntax for both up() and down() to rename and revert the column name.
    async up(queryRunner) {
      await queryRunner.query(`ALTER TABLE accounts CHANGE username user_name varchar(255)`);
    }
    async down(queryRunner) {
      await queryRunner.query(`ALTER TABLE accounts CHANGE user_name username varchar(255)`);
    }
    uses MySQL-specific CHANGE syntax which may not be portable.
    async up(queryRunner) {
      await queryRunner.query(`ALTER TABLE accounts DROP COLUMN username`);
      await queryRunner.query(`ALTER TABLE accounts ADD COLUMN user_name varchar(255)`);
    }
    async down(queryRunner) {
      await queryRunner.query(`ALTER TABLE accounts DROP COLUMN user_name`);
      await queryRunner.query(`ALTER TABLE accounts ADD COLUMN username varchar(255)`);
    }
    drops and adds columns, losing data.
    async up(queryRunner) {
      await queryRunner.query(`RENAME COLUMN username TO user_name`);
    }
    async down(queryRunner) {
      await queryRunner.query(`RENAME COLUMN user_name TO username`);
    }
    misses the table name in the query, causing error.
  3. Final Answer:

    ALTER TABLE accounts RENAME COLUMN username TO user_name -> Option A
  4. Quick Check:

    Rename column with ALTER TABLE RENAME COLUMN [OK]
Hint: Use ALTER TABLE RENAME COLUMN for renaming columns [OK]
Common Mistakes:
  • Dropping and adding columns instead of renaming
  • Omitting table name in ALTER TABLE
  • Using database-specific syntax without checking compatibility
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard