def getDatafileFormat(client, case): l = case['dfformat'].split(':') query = Query(client, "DatafileFormat", conditions={ "name": "= '%s'" % l[0], }) if len(l) > 1: query.addConditions({"version": "= '%s'" % l[1]}) return (client.assertedSearch(query)[0])
def test_query_limit(client): """Add a LIMIT clause to the last example. """ query = Query(client, "Rule", order=['grouping', 'what', 'id'], conditions={"grouping":"IS NOT NULL"}) query.setLimit( (0,10) ) print(str(query)) res = client.search(query) assert len(res) == 10
def searchUniqueKey(self, key, objindex=None): """Search the object that belongs to a unique key. This is in a sense the inverse method to :meth:`icat.entity.Entity.getUniqueKey`, the key must previously have been generated by it. This method searches the Entity object that the key has been generated for from the server. if objindex is not :const:`None`, it is used as a cache of previously retrieved objects. It must be a dict that maps keys to Entity objects. The object retrieved by this method call will be added to this index. This method uses the JPQL inspired query syntax introduced with ICAT 4.3.0. It won't work with older ICAT servers. :param key: the unique key of the object to search for. :type key: :class:`str` :param objindex: cache of Entity objects. :type objindex: :class:`dict` :return: the object corresponding to the key. :rtype: :class:`icat.entity.Entity` :raise SearchResultError: if the object has not been found. :raise ValueError: if the key is not well formed. :raise VersionMethodError: if connected to an ICAT server older then 4.3.0. """ if self.apiversion < '4.3': raise VersionMethodError("searchUniqueKey", self.apiversion) if objindex is not None and key in objindex: return objindex[key] us = key.index('_') beanname = key[:us] av = parse_attr_val(key[us+1:]) info = self.getEntityInfo(beanname) query = Query(self, beanname) for f in info.fields: if f.name in av.keys(): attr = f.name if f.relType == "ATTRIBUTE": cond = "= '%s'" % simpleqp_unquote(av[attr]) query.addConditions({attr:cond}) elif f.relType == "ONE": rk = str("%s_%s" % (f.type, av[attr])) ro = self.searchUniqueKey(rk, objindex) query.addConditions({"%s.id" % attr:"= %d" % ro.id}) else: raise ValueError("malformed '%s': invalid attribute '%s'" % (key, attr)) obj = self.assertedSearch(query)[0] if objindex is not None: objindex[key] = obj return obj
def test_query_limit_placeholder(client): """LIMIT clauses are particular useful with placeholders. """ query = Query(client, "Rule", order=['grouping', 'what', 'id'], conditions={"grouping":"IS NOT NULL"}) query.setLimit( ("%d","%d") ) print(str(query)) print(str(query) % (0,30)) res = client.search(str(query) % (0,30)) assert len(res) == 30 print(str(query) % (30,30)) res = client.search(str(query) % (30,30)) assert len(res) == 14
def test_query_aggregate_distinct_attribute(client): """Test DISTINCT on an attribute in the search result. Support for adding aggregate functions has been added in Issue #32. """ require_icat_version("4.7.0", "SELECT DISTINCT in queries") query = Query(client, "Datafile", attribute="datafileFormat.name", conditions={ "dataset.investigation.id": "= %d" % investigation.id }) print(str(query)) res = client.search(query) assert sorted(res) == ["NeXus", "NeXus", "other", "other"] query.setAggregate("DISTINCT") print(str(query)) res = client.search(query) assert sorted(res) == ["NeXus", "other"]
def searchMatching(self, obj, includes=None): """Search the matching object. Search the object from the ICAT server that matches the given object in the uniqueness constraint. >>> dataset = client.new("dataset", investigation=inv, name=dsname) >>> dataset = client.searchMatching(dataset) >>> dataset.id 172383L :param obj: an entity object having the attrinutes for the uniqueness constraint set accordingly. :type obj: :class:`icat.entity.Entity` :param includes: list of related objects to add to the INCLUDE clause of the search query. See :meth:`icat.query.Query.addIncludes` for details. :type includes: iterable of :class:`str` :return: the corresponding object. :rtype: :class:`icat.entity.Entity` :raise SearchResultError: if the object has not been found. :raise ValueError: if the object's class does not have a uniqueness constraint or if any attribute needed for the constraint is not set. """ if 'id' in obj.Constraint: raise ValueError("%s does not have a uniqueness constraint.") query = Query(self, obj.BeanName, includes=includes) for a in obj.Constraint: v = getattr(obj, a) if v is None: raise ValueError("%s is not set" % a) if a in obj.InstAttr: query.addConditions({a: "= '%s'" % v}) elif a in obj.InstRel: query.addConditions({"%s.id" % a: "= %d" % v.id}) else: raise InternalError("Invalid constraint '%s' in %s." % (a, obj.BeanName)) return self.assertedSearch(query)[0]
def test_query_aggregate_distinct_related_obj(client): """Test DISTINCT on a related object in the search result. Support for adding aggregate functions has been added in Issue #32. """ require_icat_version("4.7.0", "SELECT DISTINCT in queries") query = Query(client, "Datafile", attribute="datafileFormat", conditions={ "dataset.investigation.id": "= %d" % investigation.id }) print(str(query)) res = client.search(query) assert len(res) == 4 for n in res: assert isinstance(n, icat.entity.Entity) query.setAggregate("DISTINCT") print(str(query)) res = client.search(query) assert len(res) == 2 for n in res: assert isinstance(n, icat.entity.Entity)
def test_query_condition_list(client): """We may also add a list of conditions on a single attribute. """ condition = {"datafileCreateTime": [">= '2012-01-01'", "< '2013-01-01'"]} query = Query(client, "Datafile", conditions=condition) print(str(query)) qstr = str(query) res = client.search(query) assert len(res) == 3 # The last example also works by adding the conditions separately. query = Query(client, "Datafile") query.addConditions({"datafileCreateTime": ">= '2012-01-01'"}) query.addConditions({"datafileCreateTime": "< '2013-01-01'"}) print(str(query)) assert str(query) == qstr res = client.search(query) assert len(res) == 3
else: f = open(conf.datafile, 'r') data = yaml.load(f) f.close() # ------------------------------------------------------------ # Query examples # ------------------------------------------------------------ # To simplify things, we take search values from the example data job. inp = data['jobs']['job1']['input'] print("\nA simple query for an investigation by name.") name = inp['datasets'][0]['investigation'] q = Query(client, "Investigation", conditions={"name":"= '%s'" % name}) print(str(q)) res = client.search(q) print("%d result(s)" % len(res)) # keep the investigation id for a later example if len(res) > 0: invid = res[0].id else: # No result, use a bogus id instead invid = 4711 print("\nUse investigation id: %d" % invid) print("\nQuery a datafile by its name, dataset name, and investigation name:") df = inp['datafiles'][0] conditions = {