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_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_comment_show(self): """ Test showing an existing comment """ from aiida.cmdline.commands.cmd_comment import show from aiida.orm import Node node = Node() node.store() node.add_comment(COMMENT) result = CliRunner().invoke(show, [str(node.pk)], catch_exceptions=False) self.assertNotEqual(result.output.find(COMMENT), -1) self.assertEqual(result.exit_code, 0)
def test_comment_add(self): """ Test adding a comment """ from aiida.cmdline.commands.cmd_comment import add from aiida.orm import Node node = Node() node.store() result = CliRunner().invoke( add, ['-c{}'.format(COMMENT), str(node.pk)], catch_exceptions=False) self.assertEqual(result.exit_code, 0) comment = node.get_comments() self.assertEquals(len(comment), 1) self.assertEqual(comment[0]['content'], COMMENT)
def test_comment_remove_all(self): """ Test removing all comments from a node """ from aiida.cmdline.commands.cmd_comment import remove from aiida.orm import Node node = Node() node.store() for _ in range(10): node.add_comment(COMMENT) self.assertEqual(len(node.get_comments()), 10) result = CliRunner().invoke(remove, [str(node.pk), '--all', '--force'], catch_exceptions=False) self.assertEqual(result.exit_code, 0) self.assertEqual(len(node.get_comments()), 0)
def test_comment_remove(self): """ Test removing a comment """ from aiida.cmdline.commands.cmd_comment import remove from aiida.orm import Node node = Node() node.store() comment_id = node.add_comment(COMMENT) self.assertEquals(len(node.get_comments()), 1) result = CliRunner().invoke( remove, [str(node.pk), str(comment_id), '--force'], catch_exceptions=False) self.assertEqual(result.exit_code, 0) self.assertEquals(len(node.get_comments()), 0)
def test_create_node_and_query(self): from aiida.orm import Node from aiida.orm.querybuilder import QueryBuilder import random for i in range(100): n = Node() n.store() for idx, item in enumerate(QueryBuilder().append(Node,project=['id','label']).iterall(batch_size=10)): if idx % 10 == 10: print "creating new node" n = Node() n.store() self.assertEqual(idx,99) self.assertTrue(len(QueryBuilder().append(Node,project=['id','label']).all(batch_size=10)) > 99)
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_query_path(self): from aiida.orm.querybuilder import QueryBuilder from aiida.orm import Node n1 = Node() n1.label='n1' n1.store() n2 = Node() n2.label='n2' n2.store() n3 = Node() n3.label='n3' n3.store() n4 = Node() n4.label='n4' n4.store() n5 = Node() n5.label='n5' n5.store() n6 = Node() n6.label='n6' n6.store() n7 = Node() n7.label='n7' n7.store() n8 = Node() n8.label='n8' n8.store() n9 = Node() n9.label='n9' n9.store() # I create a strange graph, inserting links in a order # such that I often have to create the transitive closure # between two graphs n3.add_link_from(n2) n2.add_link_from(n1) n5.add_link_from(n3) n5.add_link_from(n4) n4.add_link_from(n2) n7.add_link_from(n6) n8.add_link_from(n7) for with_dbpath in (True, False): # Yet, no links from 1 to 8 self.assertEquals( QueryBuilder(with_dbpath=with_dbpath).append( Node, filters={'id':n1.pk}, tag='anc' ).append(Node, descendant_of='anc', filters={'id':n8.pk} ).count(), 0) self.assertEquals( QueryBuilder(with_dbpath=with_dbpath).append( Node, filters={'id':n8.pk}, tag='desc' ).append(Node, ancestor_of='desc', filters={'id':n1.pk} ).count(), 0) n6.add_link_from(n5) # Yet, now 2 links from 1 to 8 for with_dbpath in (True, False): self.assertEquals( QueryBuilder(with_dbpath=with_dbpath).append( Node, filters={'id':n1.pk}, tag='anc' ).append(Node, descendant_of='anc', filters={'id':n8.pk} ).count(), 2 ) self.assertEquals( QueryBuilder(with_dbpath=with_dbpath).append( Node, filters={'id':n8.pk}, tag='desc' ).append(Node, ancestor_of='desc', filters={'id':n1.pk} ).count(), 2) qb = QueryBuilder(with_dbpath=False,expand_path=True).append( Node, filters={'id':n8.pk}, tag='desc', ).append(Node, ancestor_of='desc', edge_project='path', filters={'id':n1.pk}) queried_path_set = set([frozenset(p) for p, in qb.all()]) paths_there_should_be = set([ frozenset([n1.pk, n2.pk, n3.pk, n5.pk, n6.pk, n7.pk, n8.pk]), frozenset([n1.pk, n2.pk, n4.pk, n5.pk, n6.pk, n7.pk, n8.pk]) ]) self.assertTrue(queried_path_set == paths_there_should_be) qb = QueryBuilder(with_dbpath=False, expand_path=True).append( Node, filters={'id':n1.pk}, tag='anc' ).append( Node, descendant_of='anc', filters={'id':n8.pk}, edge_project='path' ) self.assertTrue(set( [frozenset(p) for p, in qb.all()] ) == set( [frozenset([n1.pk, n2.pk, n3.pk, n5.pk, n6.pk, n7.pk, n8.pk]), frozenset([n1.pk, n2.pk, n4.pk, n5.pk, n6.pk, n7.pk, n8.pk])] )) n7.add_link_from(n9) # Still two links... for with_dbpath in (True, False): self.assertEquals( QueryBuilder(with_dbpath=with_dbpath).append( Node, filters={'id':n1.pk}, tag='anc' ).append(Node, descendant_of='anc', filters={'id':n8.pk} ).count(), 2 ) self.assertEquals( QueryBuilder(with_dbpath=with_dbpath).append( Node, filters={'id':n8.pk}, tag='desc' ).append(Node, ancestor_of='desc', filters={'id':n1.pk} ).count(), 2) n9.add_link_from(n6) # And now there should be 4 nodes for with_dbpath in (True, False): self.assertEquals( QueryBuilder(with_dbpath=with_dbpath).append( Node, filters={'id':n1.pk}, tag='anc' ).append(Node, descendant_of='anc', filters={'id':n8.pk} ).count(), 4) self.assertEquals( QueryBuilder(with_dbpath=with_dbpath).append( Node, filters={'id':n8.pk}, tag='desc' ).append(Node, ancestor_of='desc', filters={'id':n1.pk} ).count(), 4) for with_dbpath in (True, False): qb = QueryBuilder(with_dbpath=True).append( Node, filters={'id':n1.pk}, tag='anc' ).append( Node, descendant_of='anc', filters={'id':n8.pk}, edge_tag='edge' ) qb.add_projection('edge', 'depth') self.assertTrue(set(zip(*qb.all())[0]), set([5,6])) qb.add_filter('edge', {'depth':6}) self.assertTrue(set(zip(*qb.all())[0]), set([6]))
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_query_path(self): from aiida.orm.querybuilder import QueryBuilder from aiida.orm import Node from aiida.common.links import LinkType from aiida.backends.utils import QueryFactory q = QueryFactory()() n1 = Node() n1.label = 'n1' n1.store() n2 = Node() n2.label = 'n2' n2.store() n3 = Node() n3.label = 'n3' n3.store() n4 = Node() n4.label = 'n4' n4.store() n5 = Node() n5.label = 'n5' n5.store() n6 = Node() n6.label = 'n6' n6.store() n7 = Node() n7.label = 'n7' n7.store() n8 = Node() n8.label = 'n8' n8.store() n9 = Node() n9.label = 'n9' n9.store() # I create a strange graph, inserting links in a order # such that I often have to create the transitive closure # between two graphs # I set everything as an INPUT-links now, because the QueryBuilder path query or # our custom queries don't follow other links than CREATE or INPUT n3.add_link_from(n2, link_type=LinkType.INPUT) n2.add_link_from(n1, link_type=LinkType.INPUT) n5.add_link_from(n3, link_type=LinkType.INPUT) n5.add_link_from(n4, link_type=LinkType.INPUT) n4.add_link_from(n2, link_type=LinkType.INPUT) n7.add_link_from(n6, link_type=LinkType.INPUT) n8.add_link_from(n7, link_type=LinkType.INPUT) # There are no parents to n9, checking that self.assertEqual(set([]), set(q.get_all_parents([n9.pk]))) # There is one parent to n6 self.assertEqual(set([(_, ) for _ in (n6.pk, )]), set([tuple(_) for _ in q.get_all_parents([n7.pk])])) # There are several parents to n4 self.assertEqual(set([(_.pk, ) for _ in (n1, n2)]), set([tuple(_) for _ in q.get_all_parents([n4.pk])])) # There are several parents to n5 self.assertEqual(set([(_.pk, ) for _ in (n1, n2, n3, n4)]), set([tuple(_) for _ in q.get_all_parents([n5.pk])])) # Yet, no links from 1 to 8 self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n1.pk }, tag='anc').append(Node, descendant_of='anc', filters={ 'id': n8.pk }).count(), 0) self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n8.pk }, tag='desc').append(Node, ancestor_of='desc', filters={ 'id': n1.pk }).count(), 0) n6.add_link_from(n5, link_type=LinkType.INPUT) # Yet, now 2 links from 1 to 8 self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n1.pk }, tag='anc').append(Node, descendant_of='anc', filters={ 'id': n8.pk }).count(), 2) self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n8.pk }, tag='desc').append(Node, ancestor_of='desc', filters={ 'id': n1.pk }).count(), 2) self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n8.pk }, tag='desc').append( Node, ancestor_of='desc', filters={ 'id': n1.pk }, edge_filters={ 'depth': { '<': 6 } }, ).count(), 2) self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n8.pk }, tag='desc').append( Node, ancestor_of='desc', filters={ 'id': n1.pk }, edge_filters={ 'depth': 5 }, ).count(), 2) self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n8.pk }, tag='desc').append( Node, ancestor_of='desc', filters={ 'id': n1.pk }, edge_filters={ 'depth': { '<': 5 } }, ).count(), 0) # TODO write a query that can filter certain paths by traversed ID qb = QueryBuilder().append( Node, filters={ 'id': n8.pk }, tag='desc', ).append(Node, ancestor_of='desc', edge_project='path', filters={'id': n1.pk}) queried_path_set = set([frozenset(p) for p, in qb.all()]) paths_there_should_be = set([ frozenset([n1.pk, n2.pk, n3.pk, n5.pk, n6.pk, n7.pk, n8.pk]), frozenset([n1.pk, n2.pk, n4.pk, n5.pk, n6.pk, n7.pk, n8.pk]) ]) self.assertTrue(queried_path_set == paths_there_should_be) qb = QueryBuilder().append(Node, filters={ 'id': n1.pk }, tag='anc').append(Node, descendant_of='anc', filters={'id': n8.pk}, edge_project='path') self.assertTrue( set([frozenset(p) for p, in qb.all()]) == set([ frozenset([n1.pk, n2.pk, n3.pk, n5.pk, n6.pk, n7.pk, n8.pk]), frozenset([n1.pk, n2.pk, n4.pk, n5.pk, n6.pk, n7.pk, n8.pk]) ])) n7.add_link_from(n9, link_type=LinkType.INPUT) # Still two links... self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n1.pk }, tag='anc').append(Node, descendant_of='anc', filters={ 'id': n8.pk }).count(), 2) self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n8.pk }, tag='desc').append(Node, ancestor_of='desc', filters={ 'id': n1.pk }).count(), 2) n9.add_link_from(n6, link_type=LinkType.INPUT) # And now there should be 4 nodes self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n1.pk }, tag='anc').append(Node, descendant_of='anc', filters={ 'id': n8.pk }).count(), 4) self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n8.pk }, tag='desc').append(Node, ancestor_of='desc', filters={ 'id': n1.pk }).count(), 4) qb = QueryBuilder().append(Node, filters={ 'id': n1.pk }, tag='anc').append(Node, descendant_of='anc', filters={'id': n8.pk}, edge_tag='edge') qb.add_projection('edge', 'depth') self.assertTrue(set(zip(*qb.all())[0]), set([5, 6])) qb.add_filter('edge', {'depth': 6}) self.assertTrue(set(zip(*qb.all())[0]), set([6]))