Best way to save and retrieve Enum in a database

Hi everyone,
I working to a project for using Rust in a data science field, where i need to save a matrix and its metadata in a sqlite db (I'm using the crate rusqlite because I want an embedded relational db, but the next step will be to have the choice between embedded sqlite and an external postgres db).

I have created an Enum with the possible attributes:

enum MatrixAttribute{
    features(usize),
    n_obs(usize)
}

In this experiment the attributes are only usize but I will add other vairants with other types.

My idea is to store those attributes in a table so i can ave on each row the attribute and the value (the attribute is a PK because the same attribute must be unique):

CREATE TABLE matrix_attributes (
                attribute BLOB UNIQUE,
                value BLOB , 
                PRIMARY KEY (attribute)
            );

My first thought was to create an implementation for MatrixAttribute in order to save the atttributes:

impl MatrixAttribute {
    fn insert_attributes(self,conn: &Connection) ->Result<usize, rusqlite::Error> {
        let query = "INSERT OR REPLACE INTO matrix_attributes (attribute, value) VALUES (?1, ?2)";
        match self {
            MatrixAttribute::features(f) => {conn.execute(query,(String::from("features"),f),)},
            MatrixAttribute::n_obs(n) => {conn.execute(query,(String::from("n_obs"),n),)}
        }
    }
}

But doesn't seems right and I'm not sure about finding the attribute in the table (a select with where clause looking for the attribute?, but I need another enum for the attributes without the value just to be sure I can enforce the search can be performed correctly).
I was thinking maybe the trait ToSql and FromSQL but I can't figure how to convert from the enum to two columns.
Since I'm a total noob in Rust I'll appreciate a point of view from more experienced programmers, because my approach doesn't seems right.
Thanks to all!

PS:The attributes table is really small, while only the table containing the matrix can be really big.
To be complete the table containing the matrix look like this:

CREATE TABLE matrix (
                row  INTEGER NOT NULL,
                col  INTEGER NOT NULL,
                value BLOB ,
                PRIMARY KEY (row,col)
            );
CREATE INDEX value_index ON matrix (row,col);
CREATE INDEX row_index ON matrix (row);
CREATE INDEX col_index ON matrix (col);

Why?

Yes.

You can't. Those are for scalars.

1 Like

I don't know I see other programmer using more exotic features..

Thanks for the confirmation!

Maybe I was overthinking, but having a confirmation from a more experienced rust programmer is helpful.

Code being exotic is not a feat (or goal) in itself. Often it's the exact opposite.


SQL databases are in general not good at dealing with real sum types containing associated data. Document databases that can natively index eg. JSON may make it easier to work with enums, but come their own downsides. Surprisingly, ORMs don't support enums, either.

Here's a good blog about modeling sum types in SQL by hand.

You are right..

I agree but i need only few attributes, the real load is in the table with the matrix values.

Thanks for the link.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.