2

I have hierarchy paths with varying numbers of levels (up to 4):

FACILITIES \ PARK
ROADS \ GRASS/TURF BLVD MAINTENANCE
ROADS \ SIDEWALKS \ REPLACEMENT
FACILITIES \ PARKING - MAIN ST
RECREATION \ BANDSHELL \ PROPERTY \ BUILDING-GENERAL
FACILITIES \ FIREHALL \ PLUMBING
FACILITIES

I want to parse the levels at the _\_ delimiter and insert the values into Maximo database columns:

  • WOEQ1
  • WOEQ2
  • WOEQ3
  • WOEQ4

(The length of those columns is only 10 right now. I will create proper custom columns with longer lengths later.)


What I've tried:

I've figured out how to parse the levels and insert the values into columns — IF (and that's a big IF) there are always 4 levels:

#Auto-script on WORKORDER
h = mbo.getString("HIERARCHYPATH")
mbo.setValue("WOEQ1", (h.split(' \\ '))[0][:10])
mbo.setValue("WOEQ2", (h.split(' \\ '))[1][:10])
mbo.setValue("WOEQ3", (h.split(' \\ '))[2][:10])
mbo.setValue("WOEQ4", (h.split(' \\ '))[3][:10])

But of course, I won't always have 4 levels. I can have any number of levels between 1-4.


How can I parse the backslash-delimited hierarchy path (with a varying number of levels)?

User1974
  • 276
  • 1
  • 17
  • 63
  • 1
    What should go into the database row if there are less levels than 4? – ti7 Oct 23 '20 at 17:28
  • 1
    @ti7 For the cases where there are less than 4 levels, just insert the levels that do exist into the corresponding fields (the rest of the fields can be left blank). – User1974 Oct 23 '20 at 17:30
  • It's not clear from your example how individual rows are created, or if multiple rows can be uploaded at once. (ie. does it make sense to form a big INSERT statement string, or is there some object which does this for you?) – ti7 Oct 23 '20 at 17:49

2 Answers2

4

You can let "normal" splitting divide up your rows

>>> s = """\
... FACILITIES \ PARK
... ROADS \ GRASS/TURF BLVD MAINTENANCE
... ROADS \ SIDEWALKS \ REPLACEMENT
... FACILITIES \ PARKING - MAIN ST
... RECREATION \ BANDSHELL \ PROPERTY \ BUILDING-GENERAL
... FACILITIES \ FIREHALL \ PLUMBING
... FACILITIES
... """
>>> for row in s.splitlines():
...    print(row.split(" \\ "))
...
['FACILITIES', 'PARK']
['ROADS', 'GRASS/TURF BLVD MAINTENANCE']
['ROADS', 'SIDEWALKS', 'REPLACEMENT']
['FACILITIES', 'PARKING - MAIN ST']
['RECREATION', 'BANDSHELL', 'PROPERTY', 'BUILDING-GENERAL']
['FACILITIES', 'FIREHALL', 'PLUMBING']
['FACILITIES']

Then you can iterate over your returned list, setting each value

max_col_length = 10  # to be updated by author
for row in s.splitlines():
    for index, atom in enumerate(row.split(" \\ "), 1):  # count from 1
        mbo = "create a new row"  # not shown by author
        mbo.setValue("WOEQ{}".format(index), atom[:max_col_length])
    "INSERT row if processing rows individually"
"INSERT all rows if able to upload them all at the same time"

If you need to always provide at least 4 (or N) members in your list, you could use itertools.repeat to fill in the remaining values

>>> import itertools
>>> mylist = ['RECREATION', 'BANDSHELL', 'PROPERTY']
>>> mylist.extend(list(itertools.repeat(None, 4 - len(mylist))))
>>> print(mylist)
['RECREATION', 'BANDSHELL', 'PROPERTY', None]
ti7
  • 16,375
  • 6
  • 40
  • 68
  • 1
    woops / approved, actually the index can start at 1, so I'll edit that in – ti7 Oct 23 '20 at 21:32
  • Would there be a way to adjust the script so that it nulls-out existing values in scenarios where the new hierarchypath has less than four levels? Example: if the existing values were `['RECREATION', 'BANDSHELL', 'PROPERTY', 'BUILDING-GENERAL']`, but the new values are `['RECREATION', 'BANDSHELL', 'PROPERTY']`, how could we null-out the fourth level? – User1974 Oct 29 '20 at 20:11
  • @User1973 Sure, that'll be a little dependent on your logic, but you could start with a list of `None` and bring in the members, this would also ensure you always have 4 (or N) columns – ti7 Oct 29 '20 at 20:32
  • You could also `.extend` your list from [itertools.repeat](https://docs.python.org/3/library/itertools.html#itertools.repeat) set to `4-len(members)` `mylist.extend(list(itertools.repeat(None, 4-len(mylist))))` – ti7 Oct 29 '20 at 20:34
0

This is the script I ended up going with (it's a variation of @ti7's answer).

The script nulls-out existing values in scenarios where the new hierarchypath has less than four levels.

parts = s.split(r' \ ')
for i, part in enumerate(parts, 1):
    mbo.setValue(col_prefix + str(i), part)
for i in range(len(parts)+1, 5):
    mbo.setValueNull(col_prefix + str(i))
User1974
  • 276
  • 1
  • 17
  • 63