SoftwareAG/cumulocity-python-api

mo.update() seems not working when fragment is edited by [] operator?

Closed this issue · 4 comments

Hi team,

Thank you for making such an awesome Python library, I really appreciate it!

Just a quick question:
I am trying to update a device’s fragment using mo.update() as below.
I can print mo.fragments and confirm the fragments have been changed, however, this change has not be updated to the database.

    def test1():
      mo = c8y.device_inventory.get(id=123)
      mo.fragments['c8y_Hardware']['serialNumber'] ='abc'
      print(mo.fragments)
      mo.update()

On the other hand, the below code works as expected.
The fragments has been changed by add_fragment function, and successfully updated to the database.

 def test2():
    mo = c8y.device_inventory.get(id=123)
    mo.add_fragment('c8y_Hardware',serialNumber='abc')
    print(mo.fragments)
    mo.update()

So it seems like [] operator can edit fragments on the managed object, but mo.update() will not update the fragments on the device?

Is it possible if you could tell me what I’ve done something wrong on test1()?

Or is it because the API can not tell the difference on the fragments when [] operator is used?

My c8y-api version is 1.9.1.

Much appreciated!

Regards
Henry

Hi Henry, thanks for the compliment and the issue report.
Help me a bit - the c8y_Hardware fragment is already there and you just want to add the serialNumber fragment to it? Or is the c8y_Hardware fragment not present at all?

Hi Chris,
Thanks for the lightning reply!

c8y_Hardware fragment is already there as below:

_'c8y_Hardware': {'serialNumber': '1234', 'model': 'C', 'revision': 'test by Henry'}_

I was trying to change the 'serialNumber' from '1234' to 'abc' by using method test1() as shown in my first comment.

Running test1() will print the mo.fragments as below:
'c8y_Hardware': {'serialNumber': 'abc', 'model': 'Captis Pulse 33003C', 'revision': 'test by Henry'}

But the database has not been updated after running test1().
In other word, if I print the mo.fragments again, the 'serialNumber' is still '1234':
_'c8y_Hardware': {'serialNumber': '1234', 'model': 'C', 'revision': 'test by Henry'}_

Cheers,
Henry

Hi Henry,
thanks for the response, I just needed that to setup a local test. And there I immediately spotted the issue.
mo.fragments is not intended to be used like that. The API supports both dot notation and item notation for any fragment, so you should use one of these:

mo.c8y_Hardware.serialNumber = 'abc'
mo['c8y_Hardware'] = {'serialNumber': 'abc'}

This works for all "known" fragments. If you need to add a new fragment you could use add_fragment as you did or simply use item notation again:

mo['new_thing'] = {}

Hope this helps! Christoph

Hi Chris,

Looks like I made a rookie mistake here, thank you so much!

Cheers,
Henry