Using Diesel to create a fresh database project - why do I have to keep updating models.rs and schema.rs both?

45 Views Asked by At

Background: I want to use diesel to create a brand new project, where I create a new database (i.e. no database with existing data exists). I will code and as the product specification changes, my schema will get modified.

I am coming from a Django ORM background, where I write my models and the framework generates migration to create database tables, and I always change the python models code and migrations are generated to keep database in sync with my python models automatically

For example:

    model Author
        # Django creates id = models.AutoField(primary_key=True) automatically
        name = models.CharField(max_length=100)
        age = models.IntegerField()


    model Post# 
        # Django creates id = models.AutoField(primary_key=True) automatically
        title = models.CharField(max_length=100)
        body = models.TextField()
        published = models.BooleanField()
        author = models.ForeignKey(Author, on_delete=models.CASCADE)

This is pretty much what I need to write in my models for Django to create the database migrations for me, including adding a Primary Key field (id) and creating a foreign key constraint between the Book and Author tables.

I am trying to do the same in Diesel, but I am not sure how to go about it.

I checked here - https://diesel.rs/guides/getting-started

the Setup Diesel for your Project part tells that I need to create the sql migrations on my own. However, there is a note below that says

If you prefer to generate your migrations based on Rust code instead, the diesel CLI tool provides an additional --diff-schema on the diesel migration generate command that allows to generate migrations based on the current schema definition and your database.

If I understand correctly, the steps are:

  1. I can write a schema.rs file that contains the schema for my database
diesel::table! {
    posts (id) {
        id -> Int4,
        title -> Varchar,
        body -> Text,
        published -> Bool,
    }
}

# QUESTION: the guide says that I need to generate this by hand, but in another part of the guide it says that this file is generated automatically , so I am confused
  1. I can then run diesel migration generate --diff-schema create_posts to generate the migration file for me.

Creating migrations/20160815133237_create_posts/up.sql Creating migrations/20160815133237_create_posts/down.sql

  1. What i dont understand is why the guide also tells me to create a

source/models.rs

use diesel::prelude::*;

#[derive(Queryable, Selectable)]
#[diesel(table_name = crate::schema::posts)]
#[diesel(check_for_backend(diesel::pg::Pg))]
pub struct Post {
    pub id: i32,
    pub title: String,
    pub body: String,
    pub published: bool,
}

The contents of models.rs from a logic point of view is same as schema.rs - for a given database (say Postgres), the mapping between the members of the struct Post and the diesel::table fields can be deduced easily.

My question is is there a way to automate this? Or maybe the guide is outdated?

Ideally with DRY principles, i want to keep my schema logic in exactly ONE place and have Diesel update it in all other places - instead of me having to update multiple places

  1. When I come back in a month's time and have to add a new field in the Struct Post, will the a) schema.rs be updated automatically and b) with the diesel migrate command, i can create new up and down migrations automatically?
0

There are 0 best solutions below