Gramps asks if "Save changes" for people who modified via supertool

How can I modify supertool script to avoid a problem:

When I open modified person and then close it, I am asked I I want save changes. Looks like person has some flag which indicates that person was changed, right?

[initial_statements]
...
def execute():
...
        if str(primary_surname.get_origintype()).startswith('Taken'):
            print(f"Person. {gramps_id} (female) has 'Taken' as primary surname: '{primary_surname.get_surname()}'")
            
            alt_name = Name()
            alt_name.set_first_name(nameobj.get_first_name())
            alt_name.set_surname_list([primary_surname])
            alt_name.set_type(NameType.MARRIED)
            obj.add_alternate_name(alt_name)
            
            filtered_surnames = [s for s in nameobj.get_surname_list() if not str(s.get_origintype()).startswith('Taken')]
            nameobj.set_surname_list(filtered_surnames)
            nameobj.set_type(NameType.BIRTH)
            
            # Commit the changes
            db.commit_person(obj, trans)
...

[statements]
execute()

[filter]

[expressions]

[scope]
all

[unwind_lists]
False

[commit_changes]
False

[summary_only]
True

“Commit changes” should be ‘True’

but in this case all my DB people are updated even if no changes there, just Last Changed date become the same for all them. This is not very good. Is it possible to aboid this negative effect?

You probably don’t want the scope to be ‘all’.

It is more reasonable that it would be at least filtered (only Females with other filter criteria) or (more likely) selected persons.

1 Like

Got it. But this is strange a bit. These sscripts update people and dont require save updates in the interface Supertool script to move surnames with "Patronymic" type to given names
But this script requires save changes in UI:

            myobj = obj
            new_name = Name()
            new_name.set_first_name("Maria Antonivna")
            new_name.set_surname_list([])
            new_name.set_type(NameType.BIRTH)
            myobj.set_primary_name(new_name)

            db.commit_person(myobj, trans)

Where is differense?

I remember abybody said that we need work via objects like myobj, and dont use obj directly. But I use it. Looks like I do something wrong

I didn’t validate the code. Just addressed the question asked about committing changes.

But it appears to set values blindly. So I was assuming that you were filtering to the people where the action is appropriate from outside the script. (Manually or with a series of filters.)

A deeper explanation from Perplexity in response to the prompt:

As an expert in Gramps software, including its source code, Python, database design, SQLite, and the SuperTool add-on, please explain how SuperTool uses “proxy objects” to temporarily hold changes before they are committed to the tree database. Additionally, discuss why using a db.commit_person(obj, trans) command in a SuperTool script might be appropriate or inappropriate concerning the functionality of the “commit changes” option in the GUI.

In Gramps’ SuperTool, proxy objects are used to represent internal objects temporarily. These proxy objects allow users to manipulate data without directly altering the main database. This design ensures that changes are only finalized when the user selects the “commit changes” option, providing a safe way to experiment with modifications[2].

Including a db.commit_person(obj, trans) command in a SuperTool script bypasses this safeguard by directly committing changes to the database. This can be inappropriate if it conflicts with the user’s intention to review and confirm changes through the GUI’s “commit changes” option, potentially leading to unintended data alterations.

Citations:
[1] What Are Proxy Objects - Win32 apps | Microsoft Learn
[2] isotammi-addons/source/SuperTool/README.md at master ¡ Taapeli/isotammi-addons ¡ GitHub
[3] Proxy Windows Tooling via SOCKS. Leveraging SOCKS to proxy tools from a… | by Nick Powers | Posts By SpecterOps Team Members
[4] JavaScript Proxy - 30 seconds of code
[5] SuperTools
[6] Creating commits only if changes present ¡ octokit/octokit.js ¡ Discussion #1938 ¡ GitHub
[7] Writing a SuperTool
[8] Git - git-commit Documentation

1 Like

Further…

The SuperTool’s “Commit Changes” functionality in Gramps does not perform a delta comparison between proxy objects and the main database. Instead, it commits all changes made to the processed objects in the current category when the “Commit Changes” checkbox is selected1. This approach means that any modifications made to proxy objects are applied directly to their corresponding internal Gramps objects without checking for differences. Thus, it commits changes more “blindly,” applying all modifications regardless of whether they alter the existing data or not.

1 Like

This was a tricky one. It seems that Gramps requires the surname list to be non-empty. Replace the line

new_name.set_surname_list([])  

with

new_name.set_surname_list([Surname()])  

and try again.

1 Like

But in the first script version I also used non-empty:

def execute():
...
        if str(primary_surname.get_origintype()).startswith('Taken'):
            print(f"Person. {gramps_id} (female) has 'Taken' as primary surname: '{primary_surname.get_surname()}'")
            
            alt_name = Name()
            alt_name.set_first_name(nameobj.get_first_name())
            alt_name.set_surname_list([primary_surname])

But anyway I had the same behaviour. I already executed the script, then opened all updated people and clicked Save for all them. Anyway this is much more faster than edit 1300 females manually. Totally I saved about 5 hours of 7.5 hours. But if you know more ideas I will be glad hear them to avoid this trouble in the future. Thanks!

Maybe the reason is that there is also this line:

nameobj.set_surname_list(filtered_surnames)

and the “filtered_surnames” list could be empty?

1 Like

@kku and a question or maybe for future improvement… Is it possible dont apply “commit” option for entities (e.g. for people), what were not changed? Does it make sense? I undersand that I can filter all them via filter, but I dont know how make for example the above changes via proxies, but I can use this documentation to make everything what I need The gramps.gen.lib Module — Gramps 5.1.0 documentation
But if I dont use proxy, commits checkbot doesnt work.

Good question. I have not thought about that. Will investigate.

1 Like

Hm, you are right…

filtered_surnames = [s for s in nameobj.get_surname_list() if not str(s.get_origintype()).startswith('Taken')]

All these 1300 females had “Married” type as primary with one Surname only. And I changed “Married” type to “Birth” type and moved that only one surname to alternate names. So in all 100% items my filtered_surnames were empty. I understoot it later when logged it. Look like I should find a way just clear surnames list for “Birth” type?

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.