Hi everyone, how are you?
I would like to understand some points, I have a 1 to N relationship of a table called Agents and Tasks
This is my schema.rs
// @generated automatically by Diesel CLI.
diesel::table! {
agent (id) {
id -> Text,
address -> Text,
port -> Integer,
}
}
diesel::table! {
task (id) {
id -> Integer,
task_name -> Text,
agent_id -> Text,
}
}
diesel::joinable!(task -> agent (agent_id));
diesel::allow_tables_to_appear_in_same_query!(
agent,
task,
);
and in my Task Model, I have two structs, a TaskDTO and a Task, correct me but the first question is this, are the macro patterns correct in each struct? Since from what I understand DTO is what interfaces the data to the database and the Task is what will represent the data in the application.
use serde::{Serialize, Deserialize};
use diesel::sqlite::SqliteConnection;
use diesel::{
prelude::*, Queryable, Insertable, Selectable
};
use crate::schema::task::{self, dsl::*};
use crate::schema::agent::{self, dsl::*};
use super::agent::Agent;
#[derive(Queryable, Serialize, Deserialize)]
pub struct Task {
pub task_name: String,
pub agent_id: String,
}
#[derive(Queryable, Serialize, Deserialize)]
pub struct TaskByAgent {
pub task_name: String,
}
#[derive(Insertable, Serialize, Deserialize, Selectable)]
#[diesel(belongs_to(AgentDTO, foreign_key = agent_id))]
#[table_name = "task"]
pub struct TaskDTO {
pub task_name: String,
pub agent_id: String,
}
impl Task {
pub fn insert(new_task: TaskDTO, conn: &mut SqliteConnection) -> QueryResult<usize> {
diesel::insert_into(task)
.values(&new_task)
.execute(conn)
}
pub fn find_all(conn: &mut SqliteConnection) -> QueryResult<Vec<Task>> {
task.select((task_name, agent_id))
.load::<Task>(conn)
}
pub fn find_by_agent_id(other_agent_id: String, conn: &mut SqliteConnection) -> QueryResult<Vec<TaskByAgent>> {
task.filter(agent_id.eq(other_agent_id))
.select(task_name)
.load::<TaskByAgent>(conn)
}
}
An example of logging this data, where I am retrieving the entire table
[
{
"task_name": "test_task",
"agent_id": "9213fe7a-c4c6-4d4b-9e92-ceb8c574363b"
},
{
"task_name": "test_task#2",
"agent_id": "0fb81f6f-4471-4145-974c-96904b71aa18"
},
{
"task_name": "test_task#3",
"agent_id": "0fb81f6f-4471-4145-974c-96904b71aa18"
},
{
"task_name": "test_task#4",
"agent_id": "0fb81f6f-4471-4145-974c-96904b71aa18"
}
]
I just want to find the tasks of a given agent using its uuid, so I created a function that returns only the task_name column and ignores the others, and I started having an error in the conn variable where it says
he trait bound
TaskByAgent: Queryable<diesel::sql_types::Text, _>
is not satisfied
the traitQueryable<(_,), _>
is implemented forTaskByAgent
for that trait implementation, expected(_,)
, founddiesel::sql_types::Text
required forTaskByAgent
to implementFromSqlRow<diesel::sql_types::Text, _>
required fordiesel::sql_types::Text
to implementload_dsl::private::CompatibleType<TaskByAgent, _>
required forSelectStatement<FromClause<table>, SelectClause<task_name>, NoDistinctClause, WhereClause<Grouped<...>>>
to implementLoadQuery<'_, _, TaskByAgent>
#[derive(Queryable, Serialize, Deserialize)]
pub struct TaskByAgent {
pub task_name: String,
}
pub fn find_by_agent_id(other_agent_id: String, conn: &mut SqliteConnection) -> QueryResult<Vec<TaskByAgent>> {
task.filter(agent_id.eq(other_agent_id))
.select(task_name)
.load::<TaskByAgent>(conn)
}
In my head the problem was finding a compatible struct to deserialize the data coming from the bank, that's why I created this TaskByAgent but I'm still having an error, I tried to follow some solutions suggested by the AI, but it didn't reach something acceptable in my opinion, could you help me understand this?