def test_date(self): from aiida.orm.querybuilder import QueryBuilder from aiida.utils import timezone from datetime import timedelta from aiida.orm.node import Node n = Node() now = timezone.now() n._set_attr('now', now) n.store() qb = QueryBuilder().append(Node, filters={ 'attributes.now': { "and": [ { ">": now - timedelta(seconds=1) }, { "<": now + timedelta(seconds=1) }, ] } }) self.assertEqual(qb.count(), 1)
def test_joins1(self): from aiida.orm import Node, Data, Calculation from aiida.orm.querybuilder import QueryBuilder # Creating n1, who will be a parent: parent=Node() parent.label = 'mother' good_child=Node() good_child.label='good_child' good_child._set_attr('is_good', True) bad_child=Node() bad_child.label='bad_child' bad_child._set_attr('is_good', False) unrelated = Node() unrelated.label = 'unrelated' for n in (good_child, bad_child, parent, unrelated): n.store() good_child.add_link_from(parent, label='parent') bad_child.add_link_from(parent, label='parent') # Using a standard inner join qb = QueryBuilder() qb.append(Node, tag='parent') qb.append(Node, tag='children', project='label', filters={'attributes.is_good':True}) self.assertEqual(qb.count(), 1) qb = QueryBuilder() qb.append(Node, tag='parent') qb.append(Node, tag='children', outerjoin=True, project='label', filters={'attributes.is_good':True}) self.assertEqual(qb.count(), 1)
def test_attribute_existence(self): # I'm storing a value under key whatever: from aiida.orm.node import Node from aiida.orm.querybuilder import QueryBuilder val = 1. res_uuids = set() n1 = Node() n1._set_attr("whatever", 3.) n1._set_attr("test_case", "test_attribute_existence") n1.store() # I want all the nodes where whatever is smaller than 1. or there is no such value: qb = QueryBuilder() qb.append(Node, filters={ 'or': [{ 'attributes': { '!has_key': 'whatever' } }, { 'attributes.whatever': { '<': val } }], }, project='uuid') res_query = set([str(_[0]) for _ in qb.all()]) self.assertEqual(res_query, res_uuids)
def test_ordering_limits_offsets_of_results_for_SQLA(self): from aiida.orm import Node from aiida.orm.querybuilder import QueryBuilder # Creating 10 nodes with an attribute that can be ordered for i in range(10): n = Node() n._set_attr('foo', i) n.store() qb = QueryBuilder().append( Node, project='attributes.foo' ).order_by( {Node:{'attributes.foo':{'cast':'i'}}} ) res = list(zip(*qb.all())[0]) self.assertEqual(res, range(10)) # Now applying an offset: qb.offset(5) res = list(zip(*qb.all())[0]) self.assertEqual(res, range(5,10)) # Now also applying a limit: qb.limit(3) res = list(zip(*qb.all())[0]) self.assertEqual(res, range(5,8))
def test_subclassing(self): from aiida.orm.data.structure import StructureData from aiida.orm.data.parameter import ParameterData from aiida.orm import Node, Data from aiida.orm.querybuilder import QueryBuilder s = StructureData() s._set_attr('cat', 'miau') s.store() d = Data() d._set_attr('cat', 'miau') d.store() p = ParameterData(dict=dict(cat='miau')) p.store() n = Node() n._set_attr('cat', 'miau') n.store() # Now when asking for a node with attr.cat==miau, I want 4 esults: qb = QueryBuilder().append(Node, filters={'attributes.cat': 'miau'}) self.assertEqual(qb.count(), 4) qb = QueryBuilder().append(Data, filters={'attributes.cat': 'miau'}) self.assertEqual(qb.count(), 3) # If I'm asking for the specific lowest subclass, I want one result for cls in (StructureData, ParameterData): qb = QueryBuilder().append(cls, filters={'attributes.cat': 'miau'}) self.assertEqual(qb.count(), 1) # Now I am not allow the subclassing, which should give 1 result for each for cls in (StructureData, ParameterData, Node, Data): qb = QueryBuilder().append(cls, filters={'attributes.cat': 'miau'}, subclassing=False) self.assertEqual(qb.count(), 1)
def test_ordering_limits_offsets_of_results_general(self): from aiida.orm import Node from aiida.orm.querybuilder import QueryBuilder # Creating 10 nodes with an attribute that can be ordered for i in range(10): n = Node() n._set_attr('foo', i) n.store() qb = QueryBuilder().append( Node, project='attributes.foo' ).order_by({Node:'ctime'}) res = list(zip(*qb.all())[0]) self.assertEqual(res, range(10)) # Now applying an offset: qb.offset(5) res = list(zip(*qb.all())[0]) self.assertEqual(res, range(5,10)) # Now also applying a limit: qb.limit(3) res = list(zip(*qb.all())[0]) self.assertEqual(res, range(5,8)) # Specifying the order explicitly the order: qb = QueryBuilder().append( Node, project='attributes.foo' ).order_by({Node:{'ctime':{'order':'asc'}}}) res = list(zip(*qb.all())[0]) self.assertEqual(res, range(10)) # Now applying an offset: qb.offset(5) res = list(zip(*qb.all())[0]) self.assertEqual(res, range(5,10)) # Now also applying a limit: qb.limit(3) res = list(zip(*qb.all())[0]) self.assertEqual(res, range(5,8)) # Reversing the order: qb = QueryBuilder().append( Node, project='attributes.foo' ).order_by({Node:{'ctime':{'order':'desc'}}}) res = list(zip(*qb.all())[0]) self.assertEqual(res, range(9, -1, -1)) # Now applying an offset: qb.offset(5) res = list(zip(*qb.all())[0]) self.assertEqual(res, range(4,-1,-1)) # Now also applying a limit: qb.limit(3) res = list(zip(*qb.all())[0]) self.assertEqual(res, range(4,1, -1))
def test_simple_query_2(self): from aiida.orm.querybuilder import QueryBuilder from aiida.orm import Node from datetime import datetime from aiida.common.exceptions import MultipleObjectsError, NotExistent n0 = Node() n0.label = 'hello' n0.description='' n0._set_attr('foo', 'bar') n1 = Node() n1.label='foo' n1.description='I am FoO' n2 = Node() n2.label='bar' n2.description='I am BaR' n2.add_link_from(n1, label='random_2') n1.add_link_from(n0, label='random_1') for n in (n0, n1, n2): n.store() qb1 = QueryBuilder() qb1.append(Node, filters={'label': 'hello'}) self.assertEqual(len(list(qb1.all())), 1) qh = { 'path': [ { 'cls': Node, 'tag': 'n1' }, { 'cls': Node, 'tag': 'n2', 'output_of': 'n1' } ], 'filters': { 'n1': { 'label': {'ilike': '%foO%'}, }, 'n2': { 'label': {'ilike': 'bar%'}, } }, 'project': { 'n1': ['id', 'uuid', 'ctime', 'label'], 'n2': ['id', 'description', 'label'], } } qb2 = QueryBuilder(**qh) resdict = qb2.dict() self.assertEqual(len(resdict), 1) self.assertTrue(isinstance(resdict[0]['n1']['ctime'], datetime)) res_one = qb2.one() self.assertTrue('bar' in res_one) qh = { 'path': [ { 'cls': Node, 'tag': 'n1' }, { 'cls': Node, 'tag': 'n2', 'output_of': 'n1' } ], 'filters': { 'n1--n2': {'label': {'like': '%_2'}} } } qb = QueryBuilder(**qh) self.assertEqual(qb.count(), 1) # Test the hashing: query1 = qb.get_query() qb.add_filter('n2', {'label': 'nonexistentlabel'}) self.assertEqual(qb.count(), 0) with self.assertRaises(NotExistent): qb.one() with self.assertRaises(MultipleObjectsError): QueryBuilder().append(Node).one() query2 = qb.get_query() query3 = qb.get_query() self.assertTrue(id(query1) != id(query2)) self.assertTrue(id(query2) == id(query3))