When working on a codebase with a number of other developers migrations can cause database conflicts. One simple step to stop migrations failing when switching between development branches is to add IF NOT EXISTS when creating a table.

The Problem

Let's say we have a migration like the following.

CREATE TABLE tickets (
    id SERIAL PRIMARY KEY,

    title VARCHAR(140) NOT NULL,
    content VARCHAR(500) NOT NULL,

    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
);

This is perfectly fine. It creates the tickets table. But what if we are working on this feature and then have to switch to another part way through? Well we checkout the other feature branch and work away. Now it's time to come back to the tickets feature. Let's say we have to build the application locally when working on it. Once we try to build the app the migrations will fail. Why? because the tickets table already exists, from when we were previously working on the feature and ran the migration.

The Solution

Well that's annoying right? one solution would be to rollback the migration or delete the correct row in our migrations table. But we can prevent this problem from ever happening in the first place by adding CREATE TABLE IF NOT EXISTS to our migration. It now looks like this.

CREATE TABLE IF NOT EXISTS tickets (
    id SERIAL PRIMARY KEY,

    title VARCHAR(140) NOT NULL,
    content VARCHAR(500) NOT NULL,

    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
);

It may seem like an obvious thing but I've been working on a codebase recently where the teams have not been doing this. It leads to annoying failures when checking out different branches. So make sure to apply this when writing SQL migrations.

Those lucky ones working on Laravel, Django, or Rails apps will never face this issue. This is a burden of the enterprise Java developer.