-
Notifications
You must be signed in to change notification settings - Fork 66
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
JSON decoding/encoding, dumpers/loaders, extensions and system fields #225
Conversation
* Changes e.g. "pytest" to "python -m pytest". This ensures that all commands are using the version installed inside the virtualenv and not accidentally a globally installed version.
* Clean up package dependencies to align with coordinator packages released in Invenio v3.3. * Bump version of dependent packages jsonref, jsonresolver, jsonschema and jsonpatch to use more recently released versions. Some of the minimal versions of packages where dating back to 2013 (7 years ago).
* Adds usage of docker-services-cli to have more reproducible ci tests.
970d97d
to
820372d
Compare
* Adds support for encoding/decoding the JSON data store in the database. This allow e.g. providing an encoder that converts ISO-formatted timestamps to Python datetime objects. * Adds new hybrid SQLAlchemy property "is_deleted" on the model to determine if deleted or not. This makes it more clear that a null value in the json column means that a record has been soft-deleted.
* Adds a new feature to dump and load a record. This will be used by to e.g. harmonize access to records loaded via e.g. the database, Elasticsearch or third-party systems.
* System fields provides managed access to the record's dictionary. By default this behavior is not enabled on the records. * Adds extension capabilities of the record API, so that it's possible to make e.g. a system fields extension that can hook into the record API. In many ways, this is similar to the signals, but provides a more strict and extensible API.
* Adds a method "clear_none()" which helps removing None and empty list/dict values from the dictionary. * Adds a method "dict_lookup()" to support dot key string notation for looking up a key in a dictionary.
* Adds feature that allow system fields to take arguments from the initialization/creation of records. For instance, Record.create({}, metadata={...}). * System fields now saves the class attribute name on the class they are installed. This allow using the name for the above feature. * Changes create() method to initialize the database model before running the validation. This makes sense because the validation has to run on the JSON and not on the python dictionary. * Fixes arguments that are passed the JSONSchema validator, as only the format_checker and cls parameters can be passed. We do this, because we want to use the keyword arguments for initializing system fields. * Adds possibility to specify a default validator as was also possible with the format_checker. It does not makes sense to pass a validator in the create/commit methods. * Fix a couple of bugs and improve test coverage.
* Adds possibility to not add a key name and instead use the attribute name as default.
* Adds support for automatically determine which data type a given model field should be dumped as. This avoids having to specify the dump type ModelField system fields.
* Fixes a bug in the ConstantField that would cause an error when an deleted record was loaded.
* Adds a new method to the API to undelete a record after it's been soft-deleted. This enables that you can again call record.commit(), and create a new version of the record.
Merging as discussed in the architects meeting. Releasing as Invenio 1.4.0a1 |
|
||
|
||
class Record(RecordBase): | ||
"""Define API for metadata creation and manipulation.""" | ||
|
||
model_cls = RecordMetadata | ||
send_signals = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this also for backward compat? Otherwise I would personally try to abandon signals.
"""Called after a record is created.""" | ||
|
||
def pre_commit(self, record): | ||
"""Called before a record is committed.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not a post_commit
? In ILS, we have a use case that we want to re-fetch book covers from the external provider after a record has been updated.
I guess any way that such use cases will be implemented in invenio-records-resources
...
|
||
Uses the attribute name if the key is not defined. | ||
""" | ||
return self._key or self._attr_name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can it be that both are None
?
Adds support for JSON encoding/decoding to/from the database. This allows e.g. have records with complex data types such as
datetime
objects. JSONSchema validation happens on the JSON encoded version of the record.Adds dumpers to support dumping and loading records from secondary copies (e.g. records stored in an Elasticsearch index).
Adds support record extensions as a more strict replacement of signals. Allows writing extensions (like the system fields), that integrate into the Records API.
Adds support for system fields, that are Python data descriptors on the Record which allows for managed access to the Record's dictionary.
Adds support for disabling signals. Some signals can never have been used as they don't make sense (e.g. for
revert()
).Backward compatibility note
Record
class behaves as previously. If you have subclassedRecord
, and in particular if you have overwritten thevalidate()
method, you may need to make slight changes to your record.A TL;DR example: