rustsea-query

sea-query - trait `&TableDef: Iden` is not statisfied


I'm new to sea-query and sea-schema. I've extracted the schema from an sqlite database like this:

let url = "sqlite://test.db";
let connection = SqlitePool::connect(&url).await.unwrap();

let schema_discovery = SchemaDiscovery::new(connection);
let schema = schema_discovery.discover().await?;

Now I'd like to query the connection using sea-query. This is what I've tried:

let result = Query::select()
    .from(&schema.tables[0])
    .build(SqliteQueryBuilder);

Except that this gives me the error the trait bound '&TableDef: Iden' is not satisfied. I understand that it means that I'm missing the implementation of these traits, but since this struct is part of the library, I imagine there might be a correct way of accomplishing this goal.

What am I supposed to pass to the Query builder, considering that I have no prior knowledge of the database? Saying that I have no prior knowledge means that I cannot create Enums with all tables and columns (that's why I'm discoving the schema in the first place).

I also tried looking at their documentation, but couldn't find an answer.


Solution

  • I was able to figure this out thanks to some code I found online. It seems that if you want to convert a string to a value that can be used inside a sea_query query, you should first convert it into an Alias:

    use sea_query::{Alias};
    
    // ...
    
    let result = Query::select()
        .from(Alias::new(schema.tables[0].name.clone()))
        .build(SqliteQueryBuilder);
    

    Every string you want to use inside a query should be an Alias, and that goes for the columns you want to select too.

    The complete code to get all the data from a specific table (considering "choice" as the index of the table I want in the schema) looks like this:

    let chosen_table = schema.tables[choice].name.clone();
    let table_columns = schema.tables[choice].columns.iter().map(|c| c.name.clone());
    
    let query = Query::select()
        .columns(table_columns.map(Alias::new))
        .from(Alias::new(chosen_table))
        .build(SqliteQueryBuilder);
    
    let result = sqlx::query(&query.0)
        .fetch_all(&connection)
        .await?;