Find and update child table records on the server side (python)

Hi All

I have an input source (json) which I’m reading on the server side with python. I’d like to check each record I’m reading against a child table. If the record in the child table exists, I’d like to update some values (if the record does not exist I’d like to add it - which I can already do in my code). I’m struggling with the first scenario i.e. the child table record exists, I’d like to search for it (with an id from the json file), and update it’s values. What’s the best way to do this with server-side/python ?

Hi @roryfrench,
if you already have some code, sharing it would make it easier to help you… I presume to search you would loop over the elements of the child table and try to find your hit…

So this is my code so far - it’s in a class method for a parent doctype called ‘Current Schedule’. I’m trying to update schedule activity dates if the activities exist (on the child doctype called ‘Schedule Activities’), and add them if they don’t - I’m struggling with the update bit.

with open(jsonpath,"r") as read_file:
        data = json.load(read_file)

    tasks = data.get('tasks')
    if len(tasks) > 0:
        for task in tasks:
            taskstart = task.get('startDate')
            taskfinish = task.get('finishDate')
            # check if the activity already exists within the current schedule; if it does, update the dates
            filters = {
                'name': ('like',  '{0}%'.format(self.name)),
                'activity_id': task.get('id')
            }
            existing_activity_list = frappe.get_list(doctype="Schedule Activities", filters=filters, fields=['name', 'activity_id'])
            if len(existing_activity_list) == 1: # the activity already exists; update it
                activity_name = existing_activity_list[0].get('name')
                self.logger.debug("Activity {} exists in this schedule".format(activity_name))
                existing_activity = frappe.get_doc("Schedule Activities", activity_name) # THIS IS NOT WORKING
                existing_activity.activity_start = taskstart.strip()
                existing_activity.activity_finish = taskfinish.strip()
                existing_activity.save()
            else: # the activity does not exist, so add it
                row = self.append('activities', {})
                row.activity_id = task.get('id')
                row.activity_name = task.get('name')
                row.activity_type = task.get('type')
                row.project = self.project
                row.schedule = self.name
                row.activity_start = taskstart.strip()
                row.activity_finish = taskfinish.strip()
                row.is_new = 1
                self.save()

Have you tried to look for the existing activity like this:

# check if activity is already in this schedule
exists = False
for activity in self.activities:
    if activity.activity_id == task.get('id'):
        # match, update
        activity.activity_start = taskstart.strip()
        activity.activity_finish = taskfinish.strip()
        exists = True
        break
if not exists:
    # append new activity
    ...
self.save()

Hope this helps.

2 Likes

Hi. Thanks for the reply. No I haven’t - It just seems a bit ‘long-winded’ i.e. having to iterate each time to check for a match. I thought there might be a more efficient way i.e. to simply ‘fetch’ a child record with an id and/or a filter (like using ‘get_doc’, for example). But in the meantime I’ll use your method, so thanks for the response!

Agreed that the inner loop does not seem super pretty. But as it is all in memory, I guess performance-wise this should be just as fast and we can make use of the benefit that we do not need to get the records but can simply write to the child elements…