Supertool script to move surnames with "Patronymic" type to given names

Maybe anybody will decide move middlename (I used “Patronymic” surname for this) to the given name. You can use similar script to make this. The script has strict conditions, it will not work for all DB records.


[Gramps SuperTool script file]
version=1

[title]
Append Patronymic origin surname to Given name

[description]
Discussed in Gramps support forum: 
https://gramps.discourse.group/t/supertool-script-to-move-surnames-with-patronymic-type-to-given-names/5888

[category]
People

[initial_statements]
from gramps.gen.lib import NameType, Name, Surname
from gramps.gen.lib.nameorigintype import NameOriginType

counter = 0
id_set = set()

# Function to check if a name object has a specific type (e.g., Birth, Married, etc.)
def isNameObjType(nameobj, type):
    return nameobj.get_type() == type

# Function to get the count of surnames in a list
def getSurnamesCount(surnameList):
    return len(surnameList)

# Function to get the types of surnames in a list
def getSurnameTypes(surnameList):
    surnameTypes = []
    for surnameInst in surnameList:
        surnameType = surnameInst.get_origintype()
        surnameTypes.append(surnameType)
    return surnameTypes

[statements]

# Iterate over name objects; proceed only if there's exactly one name object
if len(nameobjs) == 1:
    for nameobj in nameobjs:
        # Check if the name type is "Birth"
        if nameobj.get_type() == NameType.BIRTH:
            firstName = nameobj.get_first_name()
            surnameList = nameobj.get_surname_list()
            surnameListCount = getSurnamesCount(surnameList)
            # Proceed only if there are exactly 2 surnames
            if surnameListCount != 2:
                continue

            givenSurname = None
            patronymicSurname = None

            # Identify and assign the "Given" and "Patronymic" surname objects
            if surnameList[0].get_origintype() == 'Given':
                givenSurnameObj = surnameList[0]
                givenSurname = givenSurnameObj.get_surname()
            elif surnameList[0].get_origintype() == 'Patronymic':
                patronymicSurnameObj = surnameList[0]
                patronymicSurname = patronymicSurnameObj.get_surname()
            
            if surnameList[1].get_origintype() == 'Given':
                givenSurnameObj = surnameList[1]
                givenSurname = givenSurnameObj.get_surname()
            elif surnameList[1].get_origintype() == 'Patronymic':
                patronymicSurnameObj = surnameList[1]
                patronymicSurname = patronymicSurnameObj.get_surname()

            # If either the "Given" or "Patronymic" surname is missing, skip this record
            if givenSurname is None or patronymicSurname is None:
                continue

            # Update the first name to include the patronymic surname
            newname = nameobj
            newname.set_first_name(f"{firstname} {patronymicSurname}")
            # Update the surname list to include only the "Given" surname
            newname.set_surname_list([givenSurnameObj])

            # Commit the changes to the database
            db.commit_person(obj, trans)
            counter += 1
            print(f"{counter}). {gramps_id}")
            id_set.add(gramps_id)

# Optionally, print out the list of updated Gramps IDs separated by a custom separator
#separator = "$|^" 
#print(separator.join(id_set))

[filter]

[expressions]

[scope]
all

[unwind_lists]
False

[commit_changes]
False

[summary_only]
True

1 Like

added to the SuperTool script list

1 Like

Another one version of the script that expands on my previous script. This version is designed to handle cases where individuals have three surnames: a “Given” surname (birth surname), a “Patronymic” surname (middlename), and a “Taken” surname (married surname). The script processes these surnames by appending the “Patronymic” surname to the given name and setting the “Taken” surname as a married alternative name.

Both scripts are already tested on a big database. It works good, no issues found.

[Gramps SuperTool script file]
version=1

[title]
Handle Three Surname Types: Given, Patronymic, and Taken

[description]
This script processes individuals with exactly three surname origin types: "Given," "Patronymic," and "Taken." It appends the "Patronymic" origin surname to the given name, sets the "Given" origin surname as the primary surname, and creates an alternate name with the "Taken" surname as a married name.
see https://gramps.discourse.group/t/supertool-script-to-move-surnames-with-patronymic-type-to-given-names/5888/4

[category]
People

[initial_statements]
from gramps.gen.lib import NameType, Name, Surname
from gramps.gen.lib.nameorigintype import NameOriginType

counter = 0
id_set = set()

# Function to check if a name object has a specific type (e.g., Birth, Married, etc.)
def isNameObjType(nameobj, type):
    return nameobj.get_type() == type

# Function to get the count of surnames in a list
def getSurnamesCount(surnameList):
    return len(surnameList)

# Function to get the types of surnames in a list
def getSurnameTypes(surnameList):
    surnameTypes = []
    for surnameInst in surnameList:
        surnameType = surnameInst.get_origintype()
        surnameTypes.append(surnameType)
    return surnameTypes

[statements]
if len(nameobjs) == 1:
    for nameobj in nameobjs:
        # Check if the name type is "Birth"
        if nameobj.get_type() == NameType.BIRTH:
            firstName = nameobj.get_first_name()
            surnameList = nameobj.get_surname_list()
            surnameListCount = getSurnamesCount(surnameList)
            # Continue only if there are exactly 3 surnames
            if surnameListCount != 3:
                continue

            givenSurname = None
            patronymicSurname = None
            takenSurname = None

            # Identify and assign the "Given," "Patronymic," and "Taken" surname objects
            if surnameList[0].get_origintype() == 'Given':
                givenSurnameObj = surnameList[0]
                givenSurname = givenSurnameObj.get_surname()
            elif surnameList[0].get_origintype() == 'Taken':
                takenSurnameObj = surnameList[0]
                takenSurname = takenSurnameObj.get_surname()
            elif surnameList[0].get_origintype() == 'Patronymic':
                patronymicSurnameObj = surnameList[0]
                patronymicSurname = patronymicSurnameObj.get_surname()

            if surnameList[1].get_origintype() == 'Given':
                givenSurnameObj = surnameList[1]
                givenSurname = givenSurnameObj.get_surname()
            elif surnameList[1].get_origintype() == 'Taken':
                takenSurnameObj = surnameList[1]
                takenSurname = takenSurnameObj.get_surname()
            elif surnameList[1].get_origintype() == 'Patronymic':
                patronymicSurnameObj = surnameList[1]
                patronymicSurname = patronymicSurnameObj.get_surname()

            if surnameList[2].get_origintype() == 'Given':
                givenSurnameObj = surnameList[2]
                givenSurname = givenSurnameObj.get_surname()
            elif surnameList[2].get_origintype() == 'Taken':
                takenSurnameObj = surnameList[2]
                takenSurname = takenSurnameObj.get_surname()
            elif surnameList[2].get_origintype() == 'Patronymic':
                patronymicSurnameObj = surnameList[2]
                patronymicSurname = patronymicSurnameObj.get_surname()

            # If any of the required surnames are missing, skip this record
            if givenSurname is None or takenSurname is None or patronymicSurname is None:
                continue

            # Update the first name to include the patronymic surname
            finalName = f"{firstName} {patronymicSurname}"
            g_name = nameobj
            g_name.set_first_name(finalName)
            g_name.set_surname_list([givenSurnameObj])

            # Create a new name object for the married name
            m_name = Name()
            m_name.set_first_name(finalName)
            takenSurnameObj.set_primary(True)
            m_name.set_surname_list([takenSurnameObj])
            m_name.set_type("Married Name")

            # Set the updated names in the person object
            obj.set_alternate_names([m_name])
            obj.set_primary_name(g_name)

            # Commit the changes to the database
            db.commit_person(obj, trans)
            counter += 1
            print(f"{counter}). {gramps_id}")
            id_set.add(gramps_id)

# Optionally, print out the list of updated Gramps IDs separated by a custom separator
#separator = "$|^" 
#print("^" + separator.join(id_set) + "$")

[filter]

[expressions]

[scope]
all

[unwind_lists]
False

[commit_changes]
False

[summary_only]
True

This script saved me several weeks of boring job. Many thanks to the Supertool developers the their super tool!

FYI: I dont set [commit_changes] section to True, I use db.commit_person(obj, trans) instead. Its because the first way updates ALL people even if no changes. As a result it updates the last updated date for all them. At the same time db.commit_person(obj, trans) updates only people who meets the conditions.

1 Like

Could you describe how the data found its way into these odd locations in Gramps?

Was it an import? (If so, from which software?) Or did you try using a feature in a way that you want to change now?

(Maybe it is similar to this reason… Sometimes, when I could not find the category I wanted in the import feature, I picked a different category that I rarely used. This helped me get the data into the database. After that, I used tools in the database to change the data to the right category.)

No, it was my own way to save data. When I started use Gramps, I tried to understand where can I save middlenames. Anybody recommended me that the better way is save all surnames separately, not into one field. So, if separately - it could be surnames section only. That’s why my middlename was added into surnames list. Additional confusing (and confirmation that my way is correct) for me was the native Patronymic type, which means the same as middlename in translation. So, missing middlename field, recommendation that everything should be saving separately and native Patronymic type brought to such strange usage of Gramps functionality.

1 Like

But gedcom exports don’t work good when middlename is among surnames. Another genealogs ask me fix this problem on my side because my imports in myheritage look broken when middlename is located not near first name.

1 Like

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