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:
- I can write a
schema.rsfile 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
- I can then run
diesel migration generate --diff-schema create_poststo generate the migration file for me.
Creating migrations/20160815133237_create_posts/up.sql Creating migrations/20160815133237_create_posts/down.sql
- 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
- 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?