Python API for Apache TinkerPop's Gremlin supported databases.
- Object Mapper - Models, PropertyTypes, and Form validation
- Execute gremlin queries
- Built in QuerySets for performing standard CRUD operations on graph.
- Utilities for logging queries and performance.
- Django-ORM like search when using OGM(ex: has__id__within=[200752, 82032, 4320], has__name__startingWith="Per")( Refer search-usage.md for more)
- Index support
- Query caching support
- Asynchronous Python API.
pip install git+https://github.com/invanalabs/invana-py.git#egg=invana
or
# for latest code
pipenv install git+https://github.com/invana/invana@dev#egg=invana
from invana import InvanaGraph
from invana.ogm.models import VertexModel, EdgeModel
from invana.ogm.fields import StringProperty, DateTimeProperty, IntegerProperty, FloatProperty, BooleanProperty
from datetime import datetime
from invana.ogm import indexes
graph = InvanaGraph("ws://megamind.local:8182/gremlin", traversal_source="g")
class Project(VertexModel):
graph = graph
properties = {
'name': StringProperty(max_length=10, trim_whitespaces=True),
'description': StringProperty(allow_null=True, min_length=10),
'rating': FloatProperty(allow_null=True),
'is_active': BooleanProperty(default=True),
'created_at': DateTimeProperty(default=lambda: datetime.now())
}
indexes = (
indexes.CompositeIndex("name"),
indexes.CompositeIndex("created_at")
)
class Person(VertexModel):
graph = graph
properties = {
'first_name': StringProperty(min_length=5, trim_whitespaces=True),
'last_name': StringProperty(allow_null=True),
'username': StringProperty(default="rrmerugu"),
'member_since': IntegerProperty(),
}
indexes = (
indexes.CompositeIndex("username"),
)
class Authored(EdgeModel):
graph = graph
properties = {
'created_at': DateTimeProperty(default=lambda: datetime.now())
}
indexes = (
indexes.CompositeIndex("created_at")
)
graph.management.create_model(Project)
graph.management.rollback_open_transactions(i_understand=True)
graph.management.create_indexes_from_model(Project)
Project.objects.delete()
Person.objects.delete()
Authored.objects.delete()
person = Person.objects.get_or_create(first_name="Ravi Raja", last_name="Merugu", member_since=2000)
project = Project.objects.create(name="Hello ", rating=2.5, is_active=False)
authored_data = Authored.objects.create(person.id, project.id)
authored_list = Authored.objects.search().to_list()
project_list = Project.objects.search().to_list()
graph.close_connection()
# search by id
Project.objects.search(has__id=123).to_list()
Project.objects.search(has__id__within=[123, 232]).to_list()
# search string - eq, neq, startingWith, endingWith, containing, notStartingWith, notEndingWith, notContaining
Project.objects.search(has__name__eq="Ravi Raja").to_list()
Project.objects.search(has__name__neq="Ravi Raja").to_list()
Project.objects.search(has__name__neq="Ravi Raja").to_list()
Project.objects.search(has__name__startingWith="Ravi").to_list()
Project.objects.search(has__name__endingWith="Raja").to_list()
Project.objects.search(has__name__containing="Raja").to_list()
Project.objects.search(has__name__notStartingWith="Raja").to_list()
Project.objects.search(has__name__notEndingWith="Raja").to_list()
Project.objects.search(has__name__notContaining="Raja").to_list()
# lt, gt, lte, gte, inside, outside, between
Project.objects.search(has__member_since__lte=3000).to_list()
Project.objects.search(has__member_since__lt=3000).to_list()
Project.objects.search(has__member_since__gte=1999).to_list()
Project.objects.search(has__member_since__gt=1999).to_list()
Project.objects.search(has__member_since__inside=(1000, 3000)).to_list()
Project.objects.search(has__member_since__outside=(1000, 3000)).to_list()
Project.objects.search(has__member_since__between=(1000, 3000)).to_list()
Note: more info on usage here
You need to add indexing to run order queries efficiently. Read more here
Project.objects.search().order_by('name').to_list() # asc order
Project.objects.search().order_by('-name').to_list() # desc order
# using range for pagination
queryset = Project.objects.search().order_by('name').range(1, 10).to_list()
# using paginator
from invana.gremlin.paginator import QuerySetPaginator
page_size = 5
queryset = Project.objects.search().order_by("-serial_no")
paginator = QuerySetPaginator(queryset, page_size)
qs = paginator.page(1)
first_page = qs.to_list()
from invana import InvanaGraph
graph = InvanaGraph("ws://localhost:8182/gremlin", username="user", password="password")
results = graph.execute_query("g.V().limit(1).toList()", timeout=180)
graph.close_connection()
from invana import InvanaGraph
graph = InvanaGraph("ws://localhost:8182/gremlin", username="user", password="password")
graph.execute_query_with_callback("g.V().limit(1).next()",
lambda res: print(res.__len__()),
finished_callback=lambda: graph.close_connection(),
timeout=180)
graph.close_connection()
docker run --restart=unless-stopped -p 8182:8182 -d --name janusgraph janusgraph/janusgraph:latest
docker run --restart=unless-stopped -p 8184:8182 -d --name janusgraph-1 janusgraph/janusgraph:latest
Apache License, version 2.0