diff --git a/swh/indexer/storage/model.py b/swh/indexer/storage/model.py --- a/swh/indexer/storage/model.py +++ b/swh/indexer/storage/model.py @@ -55,12 +55,15 @@ return cls(**d) # type: ignore def unique_key(self) -> Dict: - if self.indexer_configuration_id is None: - raise ValueError( - "Can only call unique_key() on objects without " - "indexer_configuration_id." - ) - return {key: getattr(self, key) for key in self.UNIQUE_KEY_FIELDS} + obj = self + + # tool["id"] and obj.indexer_configuration_id are the same value, but + # only one of them is set for any given object + if obj.indexer_configuration_id is None: + assert obj.tool # constructors ensures tool XOR indexer_configuration_id + obj = attr.evolve(obj, indexer_configuration_id=obj.tool["id"], tool=None) + + return {key: getattr(obj, key) for key in self.UNIQUE_KEY_FIELDS} @attr.s diff --git a/swh/indexer/tests/storage/test_model.py b/swh/indexer/tests/storage/test_model.py new file mode 100644 --- /dev/null +++ b/swh/indexer/tests/storage/test_model.py @@ -0,0 +1,26 @@ +# Copyright (C) 2020 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + +from swh.indexer.storage.model import BaseRow, ContentLicenseRow + + +def test_unique_key(): + assert BaseRow(id=12, indexer_configuration_id=34).unique_key() == { + "id": 12, + "indexer_configuration_id": 34, + } + + assert BaseRow(id=12, tool={"id": 34, "name": "foo"}).unique_key() == { + "id": 12, + "indexer_configuration_id": 34, + } + + assert ContentLicenseRow( + id=12, indexer_configuration_id=34, license="BSD" + ).unique_key() == {"id": 12, "indexer_configuration_id": 34, "license": "BSD"} + + assert ContentLicenseRow( + id=12, tool={"id": 34, "name": "foo"}, license="BSD" + ).unique_key() == {"id": 12, "indexer_configuration_id": 34, "license": "BSD"}