Deleting from an associated table with a subquery using Diesel from a postgres database

做~自己de王妃 提交于 2020-04-14 08:59:09

问题


I have a query that I am trying to translate from SQL into rust/diesel but am running into issues with creating a subquery using diesel.

I am using diesel = "1.4.2" along with the postgres feature.

I have the following schema and models...

#[macro_use]
extern crate diesel;

mod schema {
    table! {
        jobs (id) {
            id -> Int4,
        }

        appointments (id) {
            id -> Int4,
        }

        categories (id) {
            id -> Int4
        }

        appointments_categories(appointment_id, category_id) {
            appointment_id -> Int4,
            category_id -> Int4
        }
    }
}

mod models {
    #[derive(Debug, Identifiable)]
    pub struct Job {
        pub id: i32,
    }

    #[derive(Debug, Identifiable)]
    pub struct Appointment {
        pub id: i32,
    }

    #[derive(Debug, Identifiable)]
    pub struct Category {
        pub id: i32,
    }

    #[derive(Debug, Identifiable)]
    #[primary_key(appointment_id, appointment_type_id)]
    pub struct AppointmentCategory {
        pub id: i32,
    }
}

fn main() {}

And then I have this SQL query:

DELETE FROM appointments_categories
WHERE ROW ("appointment_id", "category_id")
    IN (
        SELECT
            appointment.id AS appointment_id, appointments_categories. "category_id" FROM appointment
        INNER JOIN appointments_categories ON appointments_categories. "appointment_id" = appointment.id
            WHERE appointment."job_id" = 125
            LIMIT 10000);

So far I have tried to use the following approach but unable to figure out how to bind the subquery/expression.

let sub_query = appointment_dsl::appointment
    .inner_join(appt_cat_dsl::appointments_categories)
    .filter(appointment_dsl::job_id.eq(job_id))
    .select((appointment_dsl::id, appt_cat_dsl::category_id));

let rows_deleted = delete(appt_cat_dsl::appointments_categories
    .filter(sql(format!("ROW(appointmentId, appointmentTypeId) IN {}", subquery))))?;

I understand that there are other ways to write the delete query but I need to be able to limit the number of rows that it deletes. The associated/junction table is massive with 3 million rows per job and the job runs every 15min. Deleting it all at once locks the DB up so it isn't an option.

Sorry I can't make a reproducible sample on the rust playground since it doesn't have diesel.

来源:https://stackoverflow.com/questions/57022429/deleting-from-an-associated-table-with-a-subquery-using-diesel-from-a-postgres-d

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!