georm/README.md
Lucien Cartier-Tilet f2e59cee7c
All checks were successful
CI / tests (push) Successful in 7m21s
fix: correct docs.rs link and switch to GitHub repository
2025-02-01 01:59:40 +01:00

4.1 KiB
Raw Blame History

Georm

A simple, opinionated SQLx ORM for PostgreSQL

What is Georm?

Georm is a quite simple ORM built around SQLx that gives access to a few useful functions when interacting with a database, implementing automatically the most basic SQL interactions youre tired of writing.

Why is Georm?

I wanted an ORM thats easy and straightforward to use. I am aware some other projects exist, such as SeaORM, but they generally dont fit my needs and/or my wants of a simple interface. I ended up writing the ORM I wanted to use.

How is Georm?

I use it in a few projects, and Im quite happy with it right now. But of course, Im open to constructive criticism and suggestions!

How can I use it?

Georm works with SQLx, but does not re-export it itself. To get started, install both Georm and SQLx in your Rust project:

cargo add sqlx --features postgres,macros # and any other feature you might want
cargo add georm

As Georm relies heavily on the macro query_as!, the macros feature is not optional. Declare your tables in your Postgres database (you may want to use SQLxs migrate feature for this), and then declare their equivalent in Rust.

CREATE TABLE biographies (
    id SERIAL PRIMARY KEY,
    content TEXT NOT NULL
);

CREATE TABLE authors (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    biography_id INT,
    FOREIGN KEY (biography_id) REFERENCES biographies(id)
);
pub struct Author {
    pub id: i32,
    pub name: String,
}

To link a struct to a table in your database, derive the sqlx::FromRow and the georm::Georm traits.

#[derive(sqlx::FromRow, Georm)]
pub struct Author {
    pub id: i32,
    pub name: String,
}

Now, indicate with the georm proc-macro which table they refer to.

#[derive(sqlx::FromRow, Georm)]
#[georm(table = "authors")]
pub struct Author {
    pub id: i32,
    pub name: String,
}

Finally, indicate with the same proc-macro which field of your struct is the primary key in your database.

#[derive(sqlx::FromRow, Georm)]
#[georm(table = "authors")]
pub struct Author {
    #[georm(id)]
    pub id: i32,
    pub name: String,
}

Congratulations, your struct Author now has access to all the functions described in the Georm trait!

Entity relationship

It is possible to implement one-to-one, one-to-many, and many-to-many relationships with Georm. This is a quick example of how a struct with several relationships of different types may be declared:

#[derive(sqlx::FromRow, Georm)]
#[georm(
    table = "books",
    one_to_many = [
        { name = "reviews", remote_id = "book_id", table = "reviews", entity = Review }
    ],
    many_to_many = [{
        name = "genres",
        table = "genres",
        entity = Genre,
        link = { table = "book_genres", from = "book_id", to = "genre_id" }
    }]
)]
pub struct Book {
    #[georm(id)]
    ident: i32,
    title: String,
    #[georm(relation = {entity = Author, table = "authors", name = "author"})]
    author_id: i32,
}

To read more about these features, you can refer to the online documentation.