I am a beginner in EdgeDb and in one of my sample projects I created a schema in EdgeDb having a Candidate
type and it contains candidate base details plus Education details. Education
is another type that is multi linked to Candidate. Both of their structure are given below
type Candidate {
required first_name: str;
required last_name: str;
required dob: str;
required profile_summary: str;
required primary_contact_number: str;
alternate_contact_number: str;
required email: str;
hobbies: array <str>;
multi education_details: Education;
}
type Education {
required course_name: str;
required institution_name: str;
required course_start_month: str;
required course_start_year: str;
required course_end_month: str;
required course_end_year: str;
pass_percentage: str;
constraint exclusive on ((.course_name, .institution_name));
}
The candidate can have zero or more education details. They can also update these education details like delete an education details or add new education details or update an already inserted education details.I was able to insert or update education details using for loops. But can't figure out how to do delete education details if it's not there as data does not include that.
Let's say we get the data like this
{
"candidate_details": {
"id": "887d4936-c69b-11ee-b4eb-9796ea46b1cc",
"first_name": "Kiran",
"last_name": "Muralee",
"primary_contact_number": "9037682934",
"alternate_contact_number": "7112658119",
"dob": "03-10-1983",
"hobbies": [
"Pencil Drawing",
"Carroms playing"
],
"education_details": [
{
"institution_name": "BMC",
"course_name": "CSE",
"pass_percentage": "56%",
"course_start_month": "10",
"course_end_month": "6",
"course_start_year": "2006",
"course_end_year": "2010"
}
]
}
}
We can certainly do an Update using the following code
let educationDetails = await e.params({ items: e.json }, (params) => {
return e.for(e.json_array_unpack(params.items), (item) => {
return e.insert(e.Education, {
institution_name: e.cast(e.str, item.institution_name),
course_name: e.cast(e.str, item.course_name),
pass_percentage: e.cast(e.str, item.pass_percentage),
course_start_month: e.cast(e.str, item.course_start_month),
course_end_month: e.cast(e.str, item.course_end_month),
course_start_year: e.cast(e.str, item.course_start_year),
course_end_year: e.cast(e.str, item.course_end_year)
}).unlessConflict(education => ({
on : [education.institution_name, education.course_name],
else: e.update(e.Education, ()=>({
set: {
course_start_month,
course_end_month,
course_start_year,
course_end_year
}
})
});
});
}).run(client, {items:education_details}) //Get from candidate object data
e.update(e.Candidate, (candidate) => ({
filter: e.op(candidate.id, "=", e.uuid(id)),
set: {
first_name,
last_name,
dob:e.str(dob),
primary_contact_number,
alternate_contact_number,
hobbies,
profile_summary,
education_details: e.select(educationDetails),
}
})).run(client)
But how do we incorporate code so that if there is need for any Education details to get deleted along with insert/update.Also if we have nested Objects, like if there is a projects type inside Education, how are we handle those inside our code.One possible solution is to add a Education details as JSON. But is there a cleaner way to do this?.
"education_details": [
{
"institution_name": "BMC",
"course_name": "CSE",
"pass_percentage": "56%",
"course_start_month": "10",
"course_end_month": "6",
"course_start_year": "2006",
"course_end_year": "2010",
"projects": [
{
"project_name": "Medinova",
"project_description": "A project on clinic systems"
}
]
}
]
The EdgeDB documentation about Insert / Handling conflicts​ /
.unlessConflict
validates your approach for inserting or updatingEducation
: you useunlessConflict
to either insert newEducation
details or update existing ones based on a unique constraint.However, to manage deletions, you would need to:
Education
details linked to theCandidate
;Education
records not present in the incoming data.And for nested objects like
Projects
insideEducation
, you would essentially follow a similar approach. You would need to make sure eachProject
linked toEducation
is updated, inserted, or deleted as needed. That might involve additional loops and checks within eachEducation
detail.If Education details contain nested Projects and you are deleting an Education object, you will need to decide how to handle these Projects.
All that can be a bit complex because EdgeDB's query language is designed to be safe (and using strong typing) and explicit, meaning bulk deletions based on dynamic conditions will require careful handling.
It is important to handle these operations within a transaction to make sure data integrity.
EdgeDB supports transactions, so you should wrap these operations in a transaction block.
A simplified version of the process might be, using
select
anddelete
: