-1

I got this table in postgres

create table tasks_users(
  id serial primary key,
  user_id smallint,
  task_id integer,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  deleted_at TIMESTAMP WITH TIME ZONE
)

With this

table_name   | column_name |        data_type
-------------+-------------+--------------------------
 tasks_users | id          | integer
 tasks_users | user_id     | smallint
 tasks_users | task_id     | integer
 tasks_users | created_at  | timestamp with time zone
 tasks_users | deleted_at  | timestamp with time zone

I got this struct

#[derive(Serialize, Deserialize, Queryable, PostgresMapper)]
#[pg_mapper(table = "tasks_users")]
pub struct TaskUsers {
    pub id: i32,
    pub user_id: i16,
    pub task_id: Option<i32>,
    pub created_at: DateTime<Utc>,
    pub deleted_at: Option<DateTime<Utc>>,
}

and i am making a query with this:

pub async fn get_users_by_tasks(
    client: &Client,
    task_id: i32,
) -> Result<Vec<TaskUsers>, io::Error> {
    let statement = client
        .prepare("select id, user_id, created_at from tasks_users where task_id = $1 and deleted_at is null")
        .await
        .unwrap();

    let usuarios = client
        .query(&statement, &[&task_id])
        .await
        .expect("Hubo un error al recuperar los usuarios de una tarea")
        .iter()
        .map(|row| TaskUsers::from_row_ref(row).unwrap())
        .collect::<Vec<TaskUsers>>();

    Ok(usuarios)
}

But, when i am getting this error

thread 'actix-rt:worker:0' panicked at 'called `Result::unwrap()` on an `Err` value: UnknownTokioPG("invalid column `task_id`")',

is there any way to reuse the same struct or do i need to build a new one?

Dilakv
  • 83
  • 9
  • Why would making a new struct fix the problem... whatever it exactly is? – trent Aug 19 '20 at 22:21
  • if i create a struct with only `id`, `user_id` and `created_at`, the error doesn't shows up anymore. – Dilakv Aug 19 '20 at 22:35
  • Could you please update the question with the output of ` SELECT table_name, column_name, data_type FROM information_schema.columns WHERE table_name = 'tasks_users'; ` – MaxV Aug 19 '20 at 23:16
  • @MaxV i put the `create table` from postgres, is it helps? – Dilakv Aug 19 '20 at 23:25
  • @Dilakv, would you like to try using "select * from"? I guess the root cause is `TaskUsers::from_row_ref(row).unwrap()`: your select statement doesn't contain "task_id" column. The other possible solution is to replace all `unwrap` with `expect` with different messages. It should help to localize the problem. – MaxV Aug 20 '20 at 16:43
  • @MaxV i really appreciate your help, i am totally new at this language, so i did think that that fields could be optionals, but i understand that not. I can not return only some fields of that struct, i have to create a new one struct if i want to do that, right? something without `user_id` and `deleted_at`. – Dilakv Aug 20 '20 at 19:58

1 Answers1

1

There is the implementation details for PostgresMapper's derive https://docs.rs/postgres-mapper-derive/0.1.1/src/postgres_mapper_derive/lib.rs.html#120 (it looks like the github repository is unavailable at the moment).

The implementation requires all fields to be presented in provided row.

As a possible solution you can select all required columns from the table:

--- .prepare("select id, user_id, created_at from tasks_users where task_id = $1 and deleted_at is null")
+++ .prepare("select id, user_id, created_at, task_id, deleted_at  from tasks_users where task_id = $1 and deleted_at is null")

or you can create custom structure with matched fields.

MaxV
  • 2,601
  • 3
  • 18
  • 25
  • 1
    That's all that i did want to know. I have to created a new struct if I want just some fields. I am brand new at this language, so some concepts are totally new from me. I am really thankful with you. – Dilakv Aug 21 '20 at 12:29