Day: January 12, 2020

  • Database migrations with Rust and Diesel

    Diesel describes itself as

    the most productive way to interact with databases in Rust because of its safe and composable abstractions over queries.

    http://diesel.rs/

    To try it out, create a new project using Cargo

    cargo new --lib diesel_demo
    cd diesel_demo

    Then edit the Cargo.toml file to add diesel and dotenv dependencies

    Next you’ll need to install the standalone diesel CLI. In my case, I only want support for postgres so I specify this using the features flag.

    cargo install diesel_cli --no-default-features --features postgres

    Connect to Postgres and create a database called “diesel_demo” using psql.

    psql -p5432 "levinotik"
    levinotik=# create database diesel_demo;                        
    CREATE DATABASE

    Create a .env file in your project root and add a variable for your database url (I don’t have a password in this example)

    DATABASE_URL=postgres://levinotik:@localhost/diesel_demo

    If all of that is right, we can use the diesel CLI to set everything up using diesel setup

    ~/dev/rust/diesel_demo  master ✗
    » diesel setup
    Creating migrations directory at: /Users/levinotik/dev/rust/diesel_demo/migrations

    That will create a migrations folder in your project and also generate a couple migrations with helper functions that diesel uses to do its work. Your project should look something like this now

    We’re ready to create our own migration now. Once again, we’ll use the diesel CLI. For our example, we want create a movie database. To do that, we run diesel migration generate create_movies which should output this:

    Great, we’ve got migration files now for creating and reverting our migration. These files are empty. Let’s write some sql to create our migration. In up.sql add this:

    CREATE TABLE movies (
      id SERIAL PRIMARY KEY,
      title VARCHAR NOT NULL,
      director VARCHAR NOT NULL,
      release_year INTEGER NOT NULL 
    );

    And in down.sql add the sql for reverting:

    DROP TABLE movies

    Now we apply our migration with diesel migration run:

    Looks like that worked. Let’s connect to our diesel_demo database and check it out.

    Great, the movies table is there. Let’s see what that looks like:

    diesel has a redo command for checking that the down.sql works correctly.

    Looks good. Diesel ran the down.sql migration and then the up.sql again. Back in psql, we can see everything is there as it was before.

    That’s it. This is how you manage database migrations in Rust using diesel. Pretty straightforward really and much as you would expect if you’ve used any other migration management tool.

    Future posts will go over how we can write and read to/from the database using the diesel package in Rust.