-
Notifications
You must be signed in to change notification settings - Fork 183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Complex
data type and support for numbers.Complex
in database
#5561
Add Complex
data type and support for numbers.Complex
in database
#5561
Conversation
@sphuber is currently on vacation, but mentioning him here in case he doesn't see this PR |
1139053
to
ebf544d
Compare
Serialization/Deserialization of complex numbers is added to the the psql_dos and sqlite_zip backend. These are stored as objects of the form `{'__complex__': True, 'real': x.real, 'imag': x.imag}` with the `__complex__` key being used as the identifier for detecting these objects for deserializations. This transformation is not done on the level of `clean_value` but by customizing the JSON encoder/decoder of the backend. Since `clean_value` can be called multiple times on the same value thre is no clean way to distinguish complex numbers that were already transformed or custom dictionaries, which contain the `__complex__` key (For these a ValidationError is raised). Added support for complex attributes in QueryBuilder complex numbers are compared like objects. For comparisons attribute.complex.real/imag can be used Open Questions: - What are the performance implications of customising the json serialization/deserialization - Should the Jsonable class handle complex numbers?
ebf544d
to
e623589
Compare
Thanks for the PR @janssenhenning . I agree that it would be very interesting and useful to have support for complex numbers to be stored in node attributes. However, I am not sure whether the current implementation, putting the responsibility of the (de)serialization on the storage backend, is desirable. Now one could argue that it should actually go there since the task of making sure how to represent certain things in the storage backend should exactly be the responsibility of said backend. However, since storage backends are now pluginnable and can be customized complicates this a bit. It would open the situation where a database that is perfectly valid in the Of course one can say that this is not the only constraint on the storage backend, and there are other requirements that should be implemented, so having one additional requirement shouldn't matter. However, so far (at least for I think we already discussed putting this in the |
@sphuber Thank you for your feedback. I appreciate your point that these kinds of serializations/deserializations have to be more high level in order to ensure consistency. If I understand you correctly this would be a counterpart to One thing that I found tricky when trying out the serialization in |
Thinking about this more I agree that the location for this serialzation/deserialization layer is not very clear. My thought was that it would be on the same layer, where However I think the |
Alternative implementation of aiidateam#5561 These are stored as objects of the form `{'__complex__': True, 'real': x.real, 'imag': x.imag}` with the `__complex__` key being used as the identifier for detecting these objects for deserializations. For serialization/deserialization we use clean_value and a new function deserialize_value. `clean_value` is pulled out of BackendNode and is now done on the level of NodeAttributes and NodeExtras. The deserialization is added to the get/get_many and all routines of these classe Added support for complex attributes in QueryBuilder complex numbers are compared like objects. For comparisons attribute.complex.real/imag can be used Open Questions: - What are the performance implications of the added deserialization? (Since clean_value is already called I think there would be no impact from that side) - Jsonable class should handle complex numbers. Setting attributes work, but the initial check json.loads(json.dumps(...)) fails
Alternative implementation of aiidateam#5561 These are stored as objects of the form `{'__complex__': True, 'real': x.real, 'imag': x.imag}` with the `__complex__` key being used as the identifier for detecting these objects for deserializations. For serialization/deserialization we use clean_value and a new function deserialize_value. `clean_value` is pulled out of BackendNode and is now done on the level of NodeAttributes and NodeExtras. The deserialization is added to the get/get_many and all routines of these classe Added support for complex attributes in QueryBuilder complex numbers are compared like objects. For comparisons attribute.complex.real/imag can be used Open Questions: - What are the performance implications of the added deserialization? (Since clean_value is already called I think there would be no impact from that side) - Jsonable class should handle complex numbers. Setting attributes work, but the initial check json.loads(json.dumps(...)) fails
Alternative implementation of aiidateam#5561 These are stored as objects of the form `{'__complex__': True, 'real': x.real, 'imag': x.imag}` with the `__complex__` key being used as the identifier for detecting these objects for deserializations. For serialization/deserialization we use clean_value and a new function deserialize_value. `clean_value` is pulled out of BackendNode and is now done on the level of NodeAttributes and NodeExtras. The deserialization is added to the get/get_many and all routines of these classe Added support for complex attributes in QueryBuilder complex numbers are compared like objects. For comparisons attribute.complex.real/imag can be used Open Questions: - What are the performance implications of the added deserialization? (Since clean_value is already called I think there would be no impact from that side) - Jsonable class should handle complex numbers. Setting attributes work, but the initial check json.loads(json.dumps(...)) fails
Thanks again for the PR @janssenhenning . Unfortunately we have decided to not go through with it. It would introduce a significant change in the basic contract that attributes should JSON-serializable. There are already a few subtle type conversions that are done under the hood, but we don't think it is wise to start introducing more as it will make it more difficult to keep consistency across storage backends. Especially since there are still open questions about automatic deserialization in both this implementation and the alternative of #5614 Also we have not had requests for native support for complex numbers since these PRs were opened, so it does not seem to be that critical. Thanks anyway for the effort and discussion! |
See #5340
Serialization/Deserialization of complex numbers is added to the the
psql_dos and sqlite_zip backend. These are stored as objects of the form
{'__complex__': True, 'real': x.real, 'imag': x.imag}
with the__complex__
key being used as the identifier for detecting theseobjects for deserializations.
This transformation is not done on the level of
clean_value
but bycustomizing the JSON encoder/decoder of the backend. Since
clean_value
can be called multiple times on the same value there is no clean way
to distinguish complex numbers that were already transformed or custom
dictionaries, which contain the
__complex__
key (For these aValidationError is raised).
Added support for complex attributes in QueryBuilder
complex numbers are compared like objects. For comparisons
attribute.complex.real/imag can be used
Open Questions:
(For now I moved it into
aiida.storage.json
sinceaiida.common.json
is already in use)serialization/deserialization for both complex numbers and all other cases?
JsonAble
node be able to handle complex numbers?