Save any AiiDA data nodes as extras to a node?

Hi all, I want to add a dict (including StructureData) into the extras. However, this does not work because the Extras need to be JSONable objects.
For example:

from aiida.orm import Int, StructureData
from ase.build import bulk
x=Int(1)
x.store()
pt = bulk("Pt")
structure = StructureData(ase=pt)
x.base.extras.set("input", {"structure": structure})

Is there any other way to save AiiDA data nodes as extras to a node?

Hi Xing, from my side what I do is to save the uuid then of course I will have to do load_node

Indeed, I would also use the UUID (NOTE: use the UUID and not the PK, as this will change when exporting/importing!). Maybe you can be explicit and call the extra key structure_uuid).

Note that this will not make a link between the two, so for queries you cannot simply use with_* in the QueryBuilder, but will have to search by UUID. But possibly this is OK in many cases?

If you explain more your usecase, we could try to provide alternative solutions (I guess you have a simplified example here, but do you need to have an Int node and attach the StructureData to it? Maybe better to revert it, use the StructureData as the main entity (maybe putting all of them in a group), and put the number 1 as one of its extras instead?

Thanks Carlo! This is indeed one option.

It would be great if AiiDA could handle saving and loading the UUIDs automatically when setting extras.

In AiiDAlab Quantum ESPRSSO, I want to save all the parameters from the configuration step to the extras of the workchain process, so that I can reload the parameters back to the GUI. The parameters include normal Python data, as well as AiiDA data node.

Another use case, In the AiiDA-WorkTree, I want to save all the worktree data (graph with nodes and links) into the WorkTree process node, so that I can rebuild the WorkTree from the process.

The worktree data includes metadata of the nodes and links, as well as the input AiiDA data of the nodes.

I then think that indeed using the UUID is the best. Ideally, you want to have some schema and a proper serialiser and deserialiser: in this way, you can just pass your dictionary to the serialiser that will validate and replace nodes with their UUIDs, and then the deserialiser with just get the JSONable dict and replace the UUIDs with the corresponding nodes (possibly even calling the key, e.g. structure, when deserialized, and structure_uuid when serialised: e.g. it could be a very generic rule, that if there is a node you append _uuid and put the UUID, and if the key ends with _uuid, you deserialise into th node).

If you implement this once, then you can reuse it multiple times. You can try first for your usecases, and we can discuss if this is general enough to somehow promote it and document it for all users.

1 Like

Thanks! I will try to write the serializer and deserializer.

Note that we already have a serializer for this purpose. You can find it in aiida.orm.utils.serialize. There is a serialize and deserialize_unsafe method that will serialize dictionaries with nodes and other AiiDA entities to YAML.I am pretty sure you should be able to use this out of the box for your use case.

I tried aiida.orm.utils.serialize, and it works. Thanks!

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