diff --git a/gdcdatamodel/models/indexes.py b/gdcdatamodel/models/indexes.py index 50e4d99e..1344caee 100644 --- a/gdcdatamodel/models/indexes.py +++ b/gdcdatamodel/models/indexes.py @@ -62,14 +62,16 @@ def get_secondary_key_indexes(cls): #: use text_pattern_ops, allows LIKE statements not starting with % index_op = 'text_pattern_ops' - secondary_keys = {key for pair in cls.__pg_secondary_keys for key in pair} key_indexes = ( Index( index_name(cls, key), cls._props[key].astext.label(key), postgresql_ops={key: index_op}, - ) for key in secondary_keys + unique=len(keys) == 1, + ) + for keys in cls.__pg_secondary_keys + for key in keys ) lower_key_indexes = ( @@ -77,10 +79,25 @@ def get_secondary_key_indexes(cls): index_name(cls, key+'_lower'), func.lower(cls._props[key].astext).label(key+'_lower'), postgresql_ops={key+'_lower': index_op}, - ) for key in secondary_keys + ) + for keys in cls.__pg_secondary_keys + for key in keys + ) + + # __pg_secondary_keys are "uniqueKeys" in the dictionary yaml file, they are + # semantically supposed to be unique locally + unique_indexes = ( + Index( + index_name(cls, "_".join(keys) + "_uniq"), + *(func.lower(cls._props[key].astext).label(key) for key in keys), + postgresql_ops=dict((key, index_op) for key in keys), + unique=True # https://bugs.python.org/issue9232 + ) + for keys in cls.__pg_secondary_keys + if len(keys) > 1 # skip duplicate indexes ) - return tuple(key_indexes) + tuple(lower_key_indexes) + return tuple(key_indexes) + tuple(lower_key_indexes) + tuple(unique_indexes) def cls_add_indexes(cls, indexes): diff --git a/gdcdatamodel/validators/graph_validators.py b/gdcdatamodel/validators/graph_validators.py index 80748e0f..a8b798d8 100644 --- a/gdcdatamodel/validators/graph_validators.py +++ b/gdcdatamodel/validators/graph_validators.py @@ -12,8 +12,7 @@ class GDCGraphValidator(object): def __init__(self): self.schemas = gdcdictionary self.required_validators = { - 'links_validator': GDCLinksValidator(), - 'uniqueKeys_validator': GDCUniqueKeysValidator(), + 'links_validator': GDCLinksValidator() } self.optional_validators = {} diff --git a/test/test_validators.py b/test/test_validators.py index 37134f79..5e2e627a 100644 --- a/test/test_validators.py +++ b/test/test_validators.py @@ -230,18 +230,3 @@ def test_graph_validator_with_correct_node(self): 'target_type': 'sample'}]}]) self.graph_validator.record_errors(g, self.entities) self.assertEquals(0, len(self.entities[0].errors)) - - def test_graph_validator_with_existing_unique_keys(self): - with g.session_scope() as session: - node = self.create_node({'type': 'data_format', - 'props': {'name': 'test'}, - 'edges': {}}, - session) - node = self.create_node({'type': 'data_format', - 'props': {'name': 'test'}, - 'edges': {}}, - session) - self.update_schema('data_format', 'uniqueKeys', [['name']]) - self.entities[0].node = node - self.graph_validator.record_errors(g, self.entities) - self.assertEquals(['name'], self.entities[0].errors[0]['keys'])