Skip to main content

Language-Agnostic Database Change Management with Sqitch

· 7 min read
Huseyin BABAL
Software Developer

Introduction

Managing database schema changes effectively is crucial in modern software development, especially when working with multiple teams or languages. Sqitch provides a powerful, language-agnostic approach to database change management that prioritizes flexibility and traceability. This article will guide you through setting up and using Sqitch for database migrations.

Getting Started

Sqitch is an open-source tool for managing database changes. Unlike many tools tied to specific programming languages or frameworks, Sqitch focuses purely on migrations and version control, making it suitable for projects in any tech stack. It integrates well with various databases, including PostgreSQL, MySQL, SQLite, and more. Key features of Sqitch include:

  • Language independence
  • Deployment planning and verification
  • Robust dependency management
  • Integration with Git for version control

Why Sqitch?

Sqitch stands out for its:

  • Language Agnosticism: Unlike ORM-based tools, Sqitch doesn't tie migrations to a specific language or framework.
  • Fine-grained Control: You can define dependencies between migrations, ensuring a logical order of execution.
  • Reversible Changes: Sqitch supports revert scripts to roll back changes, aiding in error recovery.

Prerequisites

Before diving into Sqitch, ensure the following:

  • A version control system like Git is installed.
  • A database of your choice is set up (e.g., PostgreSQL, MySQL, or SQLite).
  • Sqitch is installed. You can follow the official installation guide.

In this article, we will be using PostgreSQL as our database. You can maintain your database in any database management system. For a convenient deployment option, consider cloud-based solutions like Rapidapp, which offers managed PostgreSQL databases, simplifying setup and maintenance.

tip

Create a free database in Rapidapp in seconds here

Setting Up Sqitch for Your Project

Initialize Sqitch

sqitch init my_project --target db:pg://localhost/my_database

This creates a sqitch.conf file and a migrations directory for your project.

If you are using Rapidapp, you can add a target as follows

sqitch target add prod "db:pg://<user>:<pw>@pg.rapidapp.io:5433/<db>?ssl=true&application_name=sqitch"

followed by;

sqitch deploy prod

Define Your First Change

sqitch add add_users_table -n "Add users table"

This creates three scripts:

  • deploy/add_users_table.sql for applying changes
  • revert/add_users_table.sql for rolling back changes
  • verify/add_users_table.sql for verifying the applied changes

Writing and Executing Migrations

Writing Deployment Scripts

Edit deploy/add_users_table.sql to include SQL for creating a table:

CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(150) UNIQUE NOT NULL
);

Defining Revert Scripts

Edit revert/add_users_table.sql to include SQL for dropping the table.

DROP TABLE IF EXISTS users;

Verification Scripts

Edit verify/add_users_table.sql to ensure the table exists.

SELECT 1 FROM information_schema.tables WHERE table_name = 'users';

Deploying Changes

sqitch deploy

Sqitch ensures changes are applied in order, respecting dependencies.

Version Control and Collaboration

With Sqitch, migration scripts are stored in the repository, making it easy to track changes and collaborate. The sqitch.plan file acts as a roadmap for your migrations.

Example Git workflow

  • Add your changes:
git add deploy/ revert/ verify/ sqitch.plan
  • Commit the changes:
git commit -m "Add users table migration"

Advanced Features

Dependency Management

Specify dependencies between migrations in the sqitch.plan file:

add_users_table
add_roles_table [add_users_table]

This ensures the add_users_table migration runs before add_roles_table.

Database Targets

Sqitch supports multiple deployment targets. Update the sqitch.conf file to define targets for staging, production, etc.

Rolling Back Changes

sqitch revert to:add_users_table

Understanding Sqitch’s Internal Tracking Table

When you deploy migrations with Sqitch, it creates and uses an internal tracking table in your database to manage the state of migrations. This table ensures migrations are executed in the correct order, tracks their deployment status, and prevents reapplying or skipping steps.

projects Table

This table tracks information about different projects managed by Sqitch. Example:

projecturicreated_atcreator_namecreator_email
my_projecthttps://github.com/my_project2024-12-12 09:00:00Alice Developer[email protected]
another_projhttps://gitlab.com/another_proj2024-11-30 14:45:00Bob Engineer[email protected]
test_projecthttps://bitbucket.org/test_proj2024-10-01 08:20:00Charlie Tester[email protected]

changes Table

The changes table is where Sqitch records every migration or database change applied to the project. Each row represents a specific change, with associated metadata to ensure traceability, accountability, and reproducibility.

Example:

change_idscript_hashchangeprojectnotecommitted_atcommitter_namecommitter_emailplanned_atplanner_nameplanner_email
e29b82fa-4d65-11e3-86e0-425861b86ab64c1a7e5379f2430c22f2d4e5b65f92dd9edc800badd_users_tablemy_projectAdds a users table to the schema2024-12-12 10:15:00Alice Developer[email protected]2024-12-11 08:00:00Bob Planner[email protected]
fbcf9d76-4d65-11e3-86e0-425861b86ab6a3f9c6e5379f2430c22f2d4e5b65f92dd9edc900aadd_orders_tablemy_projectAdds an orders table to the schema2024-12-12 11:30:00Charlie Engineer[email protected]2024-12-10 09:30:00Eve Designer[email protected]
d86e02fa-4d65-11e3-86e0-425861b86ab65d6f8e5379f2430c22f2d4e5b65f92dd9edc700cupdate_usersanother_projUpdates users with a new column2024-12-12 14:00:00Dave Maintainer[email protected]2024-12-09 12:45:00Fiona Strategist[email protected]

dependencies Table

The dependencies table in Sqitch tracks the relationships between changes, indicating which changes must be applied before others. This ensures that database migrations are executed in the correct order and that all prerequisites are satisfied before applying a change.

Example:

change_idtypedependencydependency_id
e29b82fa-4d65-11e3-86e0-425861b86ab6requireadd_users_tabled86e02fa-4d65-11e3-86e0-425861b86ab6
e29b82fa-4d65-11e3-86e0-425861b86ab6requireadd_roles_tablefbcf9d76-4d65-11e3-86e0-425861b86ab6
fbcf9d76-4d65-11e3-86e0-425861b86ab6conflictdrop_roles_tableg12f03fa-4d65-11e3-86e0-425861b86ab6
d86e02fa-4d65-11e3-86e0-425861b86ab6requireinitialize_schemah34f84fa-4d65-11e3-86e0-425861b86ab6

events Table

The events table records significant actions or milestones in the Sqitch migration process. This includes when a change is planned, executed, or reverted, providing a detailed audit trail of all operations.

Example:

eventchange_idchangeprojectnoterequiresconflictstagscommitted_atcommitter_namecommitter_emailplanned_atplanner_nameplanner_email
deploye29b82fa-4d65-11e3-86e0-425861b86ab6add_users_tablemy_projectInitial deployment of the users...initialize_schemav1.0.02024-12-12 10:30:00Alice Developer[email protected]2024-12-10 09:00:00Bob Planner[email protected]
revertfbcf9d76-4d65-11e3-86e0-425861b86ab6drop_roles_tablemy_projectReverted the roles table changes.add_roles_tablev1.0.12024-12-12 11:45:00Dave Maintainer[email protected]2024-12-10 10:00:00Eve Planner[email protected]
faild86e02fa-4d65-11e3-86e0-425861b86ab6add_orders_tablemy_projectDeployment failed due to conflict.add_users_tabledrop_orders_tablev1.0.22024-12-12 12:15:00Carol Engineer[email protected]2024-12-10 11:00:00Frank Planner[email protected]

releases Table

The releases table tracks major version releases of a project, recording metadata about when a release was installed and who performed the installation. This provides a clear audit trail for version management.

Example:

versioninstalled_atinstaller_nameinstaller_email
1.02024-12-12 14:00:00Alice Developer[email protected]
1.12024-12-15 10:30:00Bob Engineer[email protected]
2.02025-01-10 09:45:00Carol Maintainer[email protected]

tags Table

The tags table records version tags applied to a project, along with metadata about their creation, application, and associated changes. Tags act as meaningful labels (e.g., versions or milestones) for database states.

Example:

tag_idtagprojectchange_idnotecommitted_atcommitter_namecommitter_emailplanned_atplanner_nameplanner_email
abc123xyzv1.0.0my_projectdef456uvwInitial release2024-12-12 15:00:00.123456Alice Developer[email protected]2024-12-10 10:00:00.123456Bob Planner[email protected]
ghi789lmnv1.1.0my_projectxyz987qrsFeature update2024-12-15 12:00:00.654321Carol Engineer[email protected]2024-12-13 14:00:00.654321Dave Planner[email protected]
opq246stuv2.0.0my_projectklm123nopMajor upgrade2025-01-10 11:30:00.321456Frank Maintainer[email protected]2025-01-08 16:00:00.321456Eve Planner[email protected]

Conclusion

Sqitch is a robust, language-agnostic tool that simplifies database change management, making it ideal for diverse tech stacks. Its emphasis on dependencies, reversibility, and version control ensures seamless collaboration and reliable deployments. Whether you’re a seasoned developer or new to database migrations, Sqitch is worth exploring.