class Customer(OGMTestClass): username = Property() email = Property(primary_key=True) addresses = ManyToManyRelation('HAS_ADDRESS', restrict_types=('Address', ), backref='customer') orders = OneToManyRelation('PLACED_ORDER', restrict_types=('Order', ), backref='customer')
def test_node_one_unique(): person = Node('Person', SSN=Property(unique=True)) assert person.schema == ['CONSTRAINT ON ( person:Person ) ' 'ASSERT person.SSN IS UNIQUE'] assert person['SSN'].indexed assert person['SSN'].unique assert not person['SSN'].required
def test_logical_cypher_expressions(): person = Node('Person', name=Property(), var='n') match = Match(person).where(person['name'] == 'Alice') assert str(match) == 'MATCH (n:`Person`)\n WHERE n.name = {n_name}' assert len(match.params) == 1 assert 'n_name' in match.params assert match.params['n_name'] == 'Alice' match = Match(person).where(person['name'] != 'Alice') assert str(match) == 'MATCH (n:`Person`)\n WHERE n.name <> {n_name}' assert len(match.params) == 1 assert 'n_name' in match.params assert match.params['n_name'] == 'Alice' match = Match(person).where(person['name'] >= 'Alice') assert str(match) == 'MATCH (n:`Person`)\n WHERE n.name >= {n_name}' assert len(match.params) == 1 assert 'n_name' in match.params assert match.params['n_name'] == 'Alice' match = Match(person).where(person['name'] <= 'Alice') assert str(match) == 'MATCH (n:`Person`)\n WHERE n.name <= {n_name}' assert len(match.params) == 1 assert 'n_name' in match.params assert match.params['n_name'] == 'Alice' match = Match(person).where(person['name'] < 'Alice') assert str(match) == 'MATCH (n:`Person`)\n WHERE n.name < {n_name}' assert len(match.params) == 1 assert 'n_name' in match.params assert match.params['n_name'] == 'Alice' match = Match(person).where(person['name'] > 'Alice') assert str(match) == 'MATCH (n:`Person`)\n WHERE n.name > {n_name}' assert len(match.params) == 1 assert 'n_name' in match.params assert match.params['n_name'] == 'Alice'
def test_where_and_or(): person = Node('Person', name='Ali', age=Property(value=29, type=int), hair_color='red', var='n') expected_match = [ 'MATCH (n:`Person`)', ' WHERE n.name = {n_name}', ] match = Match(person.bind('name')) assert str(match) == '\n'.join(expected_match) assert len(match.params) == 1 assert 'n_name' in match.params assert match.params['n_name'] == 'Ali' match.where(person['age']) == 29 expected_match.append(' AND n.age = {n_age}') assert str(match) == '\n'.join(expected_match) assert len(match.params) == 2 assert 'n_name' in match.params assert match.params['n_name'] == 'Ali' assert 'n_age' in match.params assert match.params['n_age'] == 29 match = Match(person.bind('name')) match.where(person['age'], or_=True) == 29 expected_match.pop() expected_match.append(' OR n.age = {n_age}') assert str(match) == '\n'.join(expected_match) assert len(match.params) == 2 assert 'n_name' in match.params assert match.params['n_name'] == 'Ali' assert 'n_age' in match.params assert match.params['n_age'] == 29
def test_node_one_required(): person = Node('Person', name=Property(required=True)) assert person.schema == ['CONSTRAINT ON ( person:Person ) ' 'ASSERT exists(person.name)'] assert not person['name'].indexed assert not person['name'].unique assert person['name'].required
class Order(OGMTestClass): id = Property(type=UUID, default=uuid.uuid4, primary_key=True, indexed=True) items = OneToManyRelation('HAS_ITEM', restrict_types=(OrderItem, ), backref='order')
def test_create_node_two_labels(): expected_stmts = ('CREATE (node:`Person`:`User`)\n' ' SET node.name = {node_name}', 'CREATE (node:`User`:`Person`)\n' ' SET node.name = {node_name}') user = Node('User', 'Person', name=Property()) create = Create(user) assert str(create) in expected_stmts
def test_full_relationship_create(): expected_query = ('MATCH (m:`User`)\n' 'MATCH (n:`User`)\n' 'CREATE (m)-[rel:`KNOWS`]->(n)') user_m = Node('User', name=Property(), var='m') user_n = user_m.copy(var='n') rel = Relationship('KNOWS', user_m, user_n) query = Match(user_m) & Match(user_n) & Create(rel) assert str(query) == expected_query assert len(query.params) == 0
def test_create_node_two_props(): user = Node('User', name=Property(), age=Property(type=int)) create = Create(user) assert len(create.params) == 2 assert 'node_name' in create.params assert create.params['node_name'] is None assert 'node_age' in create.params assert create.params['node_age'] is None create.set(user['name'] == 'Frank') assert len(create.params) == 2 assert 'node_name' in create.params assert create.params['node_name'] == 'Frank' assert 'node_age' in create.params assert create.params['node_age'] is None create.set(user['age'] == '29') assert len(create.params) == 2 assert 'node_name' in create.params assert create.params['node_name'] == 'Frank' assert 'node_age' in create.params assert create.params['node_age'] == 29
def test_return(): n = Node('Person', name=Property(), x=Property(), y=Property(), var='n') match = Match(n) query = 'MATCH (n:`Person`)' assert str(match.return_()) == '\n'.join((query, 'RETURN *')) match.pop() assert str(match.return_(n)) == '\n'.join((query, 'RETURN n')) match.pop() m = Node('Person', x=Property(), var='m') match &= Match(m) query = '\n'.join((query, 'MATCH (m:`Person`)')) assert str(match.return_(n, m)) == '\n'.join((query, 'RETURN n, m')) match.pop() assert str(match.return_(n['name'])) == '\n'.join((query, 'RETURN n.name')) match.pop() assert str(match.return_(n['x'], n['y'])) == '\n'.join((query, 'RETURN n.x, n.y')) match.pop() assert str(match.return_(m['x'], n['y'])) == '\n'.join((query, 'RETURN m.x, n.y'))
def test_where_and_set(): person = Node('Person', name='Ali', age=Property(value=29, type=int), hair_color='red', var='n') expected_match = [ 'MATCH (n:`Person`)', ' WHERE n.name = {n_name}', ] match = Match(person.bind('name')) assert str(match) == '\n'.join(expected_match) assert len(match.params) == 1 assert 'n_name' in match.params assert match.params['n_name'] == 'Ali' expected_match = [ 'MATCH (n:`Person`)', ' WHERE n.name = {n_name} AND n.age = {n_age}', ] match = Match(person.bind('name', 'age')) try: assert str(match) == '\n'.join(expected_match) except AssertionError: expected_match.pop() expected_match.append( ' WHERE n.age = {n_age}' ' AND n.name = {n_name}' ) assert str(match) == '\n'.join(expected_match) assert len(match.params) == 2 assert 'n_name' in match.params assert match.params['n_name'] == 'Ali' assert 'n_age' in match.params assert match.params['n_age'] == 29 match.set(person['age'] == 30) expected_match.append(' SET n.age = {param0}') assert str(match) == '\n'.join(expected_match) assert len(match.params) == 3 assert 'n_name' in match.params assert match.params['n_name'] == 'Ali' assert 'n_age' in match.params assert match.params['n_age'] == 29 assert 'param0' in match.params assert match.params['param0'] == 30 match.set(person['name'] == 'Alison') expected_match.append(' SET n.name = {param1}') assert str(match) == '\n'.join(expected_match) assert len(match.params) == 4 assert 'n_name' in match.params assert match.params['n_name'] == 'Ali' assert 'n_age' in match.params assert match.params['n_age'] == 29 assert 'param0' in match.params assert match.params['param0'] == 30 assert 'param1' in match.params assert match.params['param1'] == 'Alison'
def test_create_node_one_prop(): expected_stmt = ('CREATE (node:`User`)\n' ' SET node.name = {node_name}') user = Node('User', name=Property()) create = Create(user) assert str(create) == expected_stmt assert len(create.params) == 1 assert 'node_name' in create.params assert create.params['node_name'] is None user.name = 'Frank' create = Create(user) assert str(create) == expected_stmt assert len(create.params) == 1 assert 'node_name' in create.params assert create.params['node_name'] == 'Frank'
def test_merge_on_create_on_match(): person = Node('Person', name=Property()) merge = ( Merge(person) .on_create() .set(person['name'] == 'Fred') .on_match() .set(person['name'] == 'Bob') ) expected_stmt = '\n'.join(( 'MERGE (node:`Person`)', 'ON CREATE', ' SET node.name = {node_name}', 'ON MATCH', ' SET node.name = {param0}' )) assert str(merge) == expected_stmt assert len(merge.params) == 2 assert 'node_name' in merge.params assert merge.params['node_name'] == 'Fred' assert 'param0' in merge.params assert merge.params['param0'] == 'Bob'
class Address(OGMTestClass): street_level = Property() city = Property()
class InternationalAddress(Address): postal_code = Property()
class DomesticAddress(Address): state = Property() zip_code = Property()
def test_property_set_once(): prop = Property() with pytest.raises(ImmutableAttributeError): prop.type = int with pytest.raises(ImmutableAttributeError): prop.indexed = False with pytest.raises(ImmutableAttributeError): prop.unique = True with pytest.raises(ImmutableAttributeError): prop.required = 5 with pytest.raises(ImmutableAttributeError): prop.primary_key = None with pytest.raises(ImmutableAttributeError): prop.read_only = "DON'T CHANGE ME" # Can change these b/c at this point they're still None prop.name = 'fred' prop.default = 5 # Type checking is still performed with pytest.raises(ValueError): prop.obj = 5 prop.obj = Node('x') with pytest.raises(ImmutableAttributeError): prop.name = 'bob' with pytest.raises(ImmutableAttributeError): prop.default = 9 with pytest.raises(ImmutableAttributeError): prop.obj = Node('y') prop = Property(default=5, obj=Node('x')) with pytest.raises(ImmutableAttributeError): prop.default = 9 with pytest.raises(ImmutableAttributeError): prop.obj = Node('y') with pytest.raises(ImmutableAttributeError): del prop.name with pytest.raises(ImmutableAttributeError): del prop.type with pytest.raises(ImmutableAttributeError): del prop.default with pytest.raises(ImmutableAttributeError): del prop.obj with pytest.raises(ImmutableAttributeError): del prop.unique with pytest.raises(ImmutableAttributeError): del prop.indexed with pytest.raises(ImmutableAttributeError): del prop.required with pytest.raises(ImmutableAttributeError): del prop.primary_key with pytest.raises(ImmutableAttributeError): del prop.read_only
class OrderItem(OGMTestClass): line_item = Property(primary_key=True) price = Property(type=money, primary_key=True)
def test_node_one_index(): person = Node('Person', name=Property(indexed=True)) assert person.schema == ['INDEX ON :Person(name)'] assert person['name'].indexed assert not person['name'].unique assert not person['name'].required
def test_arithmetic_cypher_expressions(): Person = Node('Person', age=Property(type=int), var='n') expected_stmt = ['MATCH (n:`Person`)', ''] match = Match(Person).where((Person['age'] + 5) == 23) expected_stmt[1] = ' WHERE n.age + {n_age} = {param0}' assert str(match) == '\n'.join(expected_stmt) assert match.params['n_age'] == 5 assert match.params['param0'] == 23 match = Match(Person).where((5 + Person['age']) == 23) assert str(match) == '\n'.join(expected_stmt) assert match.params['n_age'] == 5 assert match.params['param0'] == 23 match = Match(Person).where((Person['age'] - 4) == 13) expected_stmt[1] = ' WHERE n.age - {n_age} = {param0}' assert str(match) == '\n'.join(expected_stmt) assert match.params['n_age'] == 4 assert match.params['param0'] == 13 match = Match(Person).where((4 - Person['age']) == 13) expected_stmt[1] = ' WHERE {n_age} - n.age = {param0}' assert str(match) == '\n'.join(expected_stmt) assert match.params['n_age'] == 4 assert match.params['param0'] == 13 match = Match(Person).where((Person['age'] * 5) == 23) expected_stmt[1] = ' WHERE n.age * {n_age} = {param0}' assert str(match) == '\n'.join(expected_stmt) assert match.params['n_age'] == 5 assert match.params['param0'] == 23 match = Match(Person).where((5 * Person['age']) == 23) assert str(match) == '\n'.join(expected_stmt) assert match.params['n_age'] == 5 assert match.params['param0'] == 23 match = Match(Person).where((Person['age'] / 4) == 13) expected_stmt[1] = ' WHERE n.age / {n_age} = {param0}' assert str(match) == '\n'.join(expected_stmt) assert match.params['n_age'] == 4 assert match.params['param0'] == 13 match = Match(Person).where((4 / Person['age']) == 13) expected_stmt[1] = ' WHERE {n_age} / n.age = {param0}' assert str(match) == '\n'.join(expected_stmt) assert match.params['n_age'] == 4 assert match.params['param0'] == 13 match = Match(Person).where((Person['age'] % 4) == 13) expected_stmt[1] = ' WHERE n.age % {n_age} = {param0}' assert str(match) == '\n'.join(expected_stmt) assert match.params['n_age'] == 4 assert match.params['param0'] == 13 match = Match(Person).where((4 % Person['age']) == 13) expected_stmt[1] = ' WHERE {n_age} % n.age = {param0}' assert str(match) == '\n'.join(expected_stmt) assert match.params['n_age'] == 4 assert match.params['param0'] == 13 match = Match(Person).where((Person['age']**4) == 13) expected_stmt[1] = ' WHERE n.age ^ {n_age} = {param0}' assert str(match) == '\n'.join(expected_stmt) assert match.params['n_age'] == 4 assert match.params['param0'] == 13 match = Match(Person).where((4**Person['age']) == 13) expected_stmt[1] = ' WHERE {n_age} ^ n.age = {param0}' assert str(match) == '\n'.join(expected_stmt) assert match.params['n_age'] == 4 assert match.params['param0'] == 13
def test_complex_logical_cypher_expressions(): Person = Node('Person', name=Property(), hair_color=Property(), var='n') expected_match = [ 'MATCH (n:`Person`)', ' WHERE n.name = {n_name}', ' AND n.hair_color = {n_hair_color}' ] match = (Match(Person).where(Person['name'] == 'Alice').where( Person['hair_color'] == 'red')) assert str(match) == '\n'.join(expected_match) assert match.params == {'n_name': 'Alice', 'n_hair_color': 'red'} match = (Match(Person).where((Person['name'] == 'Alice'), (Person['hair_color'] == 'red'))) assert str(match) == '\n'.join((expected_match[0], ' '.join( (expected_match[1], expected_match[2].lstrip())))) assert match.params == {'n_name': 'Alice', 'n_hair_color': 'red'} Person = Node('Person', name=Property(), hair_color=Property(), age=Property(type=int), var='n') expected_match.append(' AND n.age = {n_age}') match = (Match(Person).where((Person['name'] == 'Alice'), (Person['hair_color'] == 'red'), (Person['age'] == '29'))) assert str(match) == '\n'.join((expected_match[0], ' '.join( (expected_match[1], expected_match[2].lstrip(), expected_match[3].lstrip())))) assert match.params == { 'n_name': 'Alice', 'n_hair_color': 'red', 'n_age': 29 } match = (Match(Person).where(Person['name'] == 'Alice').where( Person['hair_color'] == 'red').where(Person['age'] == 29)) assert str(match) == '\n'.join(expected_match) assert match.params == { 'n_name': 'Alice', 'n_hair_color': 'red', 'n_age': 29 } expected_match[3] = expected_match[3].replace('AND', ' OR') match = (Match(Person).where( (Person['name'] == 'Alice'), (Person['hair_color'] == 'red')).where(Person['age'] == 29, or_=True)) assert str(match) == '\n'.join((expected_match[0], ' '.join( (expected_match[1], expected_match[2].lstrip())), expected_match[3])) assert match.params == { 'n_name': 'Alice', 'n_hair_color': 'red', 'n_age': 29 } match = (Match(Person).where(Person['name'] == 'Alice').where( Person['hair_color'] == 'red').where(Person['age'] == 29, or_=True)) assert str(match) == '\n'.join(expected_match) assert match.params == { 'n_name': 'Alice', 'n_hair_color': 'red', 'n_age': 29 }