pyorient icon indicating copy to clipboard operation
pyorient copied to clipboard

What is the correctly way to delete edges with orientdb OGM in django rest framework?

Open LegolasVzla opened this issue 5 years ago • 3 comments

I was wondering if exists some command like delete_edge(), to delete a specific edge row.

I don't know how to create a method to delete edges in django rest framework, using orientdb OGM.

I'm using pyorient==1.5.5 and OrientDB 3.0.18 version.

I have two vertex Classes: ousers, ocompany. Also I have two relationships (edges) Classes: ofriends, oworksat. So for example:

To make a ofriends relationship I need two ousers. And to make a oworksat relationship I need one ouser and one ocompany. Every relationship has it own cluster id.

I know that I can access to these functions:

(Pdb) dir(graph) ['PROPERTY_TYPES', '_GROOVY_GET_DB', '_GROOVY_NULL_LISTENER', '_GROOVY_TRY', 'class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'gt', 'hash', 'init', 'le', 'lt', 'module', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', '_last_cred', '_last_db', '_last_user', 'batch', 'both', 'bothE', 'build_mapping', 'clear_registry', 'client', 'coerce_class_names', 'coerce_class_names_to_quoted', 'compute_all_properties', 'config', 'create_all', 'create_class', 'create_edge', 'create_edge_command', 'create_function', 'create_props_mapping', 'create_vertex', 'create_vertex_command', 'delete_vertex', 'delete_vertex_command', 'drop', 'drop_all', 'drop_class', 'edge_from_record', 'edges_from_records', 'element_from_link', 'element_from_record', 'elements_from_links', 'elements_from_records', 'export', 'get_edge', 'get_element', 'get_vertex', 'gremlin', 'guard_reserved_words', 'inE', 'in_', 'include', 'init_broker_for_class', 'list_superclasses', 'ocompany', 'ofriends', 'open', 'ousers', 'out', 'outE', 'oworksat', 'populate', 'property_from_schema', 'props_from_db', 'props_to_db', 'query', 'registry', 'save_element', 'scripts', 'server_version', 'strict', 'toposort_classes', 'valid_element_base', 'vertex_from_record', 'vertexes_from_records']

If I do: graph.delete_vertex("#21:0") It works good and deletes #21:0 ouser vertex row, which is part of ofriends and oworskat relationships, so also, that command deletes the relationship where that vertex is included. Obviously, I don't want to delete the entire vertex, just only the specific edge (not the class, just the relationship row).

I was wondering if exists some command like delete_edge(), but dir(graph) don't tell me nothing related.

settings.py

from pyorient.ogm import Graph, Config
from pyorient.serializations import OrientSerialization
from pyorient.ogm import declarative

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

config = RawConfigParser()
config.read(BASE_DIR + '/settings.ini')

ORIENTDB = {
    'NAME': config.get('orientdbConf', 'DB_NAME'),
    'USER': config.get('orientdbConf', 'DB_USER'),
    'PASSWORD': config.get('orientdbConf', 'DB_PASS'),
    'HOST': config.get('orientdbConf', 'DB_HOST'),
    'PORT': config.get('orientdbConf', 'DB_PORT'),
}

Config.from_url('plocal://'+ORIENTDB['HOST']+':'+str(ORIENTDB['PORT'])+'/'+ORIENTDB['NAME']+'',''+ORIENTDB['USER']+'', ''+ORIENTDB['PASSWORD']+'',initial_drop=False,serialization_type=OrientSerialization.Binary)
graph = Graph(Config.from_url(''+ORIENTDB['HOST']+'/'+ORIENTDB['NAME']+'',''+ORIENTDB['USER']+'', ''+ORIENTDB['PASSWORD']+'',initial_drop=False))
Node = declarative.declarative_node()
Relationship = declarative.declarative_relationship()

models.py

from core.settings import Node,Relationship,graph
from pyorient.ogm.property import (String, Date, DateTime, Decimal, Double,
    Integer, Boolean, EmbeddedMap, EmbeddedSet,Link, UUID)

class OUsers(Node):
    element_plural = 'ousers'
    postgresql_id=Integer(nullable=False,unique=True)

class OCompany(Node):
    element_plural = 'ocompany'
    postgresql_id=Integer(nullable=False,unique=True)

class OFriends(Relationship):
    label = 'ofriends'
    from_postgresql_ouser_id=Integer(nullable=False,unique=True)
    to_postgresql_ouser_id=Integer(nullable=False,unique=True)

class OWorksAt(Relationship):
    label = 'oworksat'
    from_postgresql_ouser_id=Integer(nullable=False,unique=True)
    to_postgresql_ocompany_id=Integer(nullable=False,unique=True)

graph.create_all(Node.registry)
graph.create_all(Relationship.registry)

serializers.py

from .models import (OUsers,OCompany,OFriends,OWorksAt)
from rest_framework import serializers
from django.contrib.auth import get_user_model
User = get_user_model()

class OFriendsSerializer(serializers.Serializer):
    from_postgresql_ouser_id = serializers.IntegerField()
    to_postgresql_ouser_id = serializers.IntegerField()

    def create(self, data):
        return OFriends.objects.create(**data)

    def update(self, instance, data):
        instance.from_postgresql_ouser_id = data.get("from_postgresql_ouser_id")
        instance.to_postgresql_ouser_id = data.get("to_postgresql_ouser_id")
        instance.save()
        return instance

class OFriendsSerializer(serializers.Serializer):
    from_postgresql_ouser_id = serializers.IntegerField()
    to_postgresql_ouser_id = serializers.IntegerField()

    def create(self, data):
        return OFriends.objects.create(**data)

    def update(self, instance, data):
        instance.from_postgresql_ouser_id = data.get("from_postgresql_ouser_id")
        instance.to_postgresql_ouser_id = data.get("to_postgresql_ouser_id")
        instance.save()
        return instance

api.py

class OFriendsViewSet(viewsets.ModelViewSet):

    def destroy(self, request, *args, **kwargs):
        queryset = graph.ofriends.query()
        import pdb;pdb.set_trace()
        # HERE should be the command 

LegolasVzla avatar Jun 09 '19 19:06 LegolasVzla

Huh, you're right!

I'm surprised that functionality was never added.

On Mon, 10 Jun 2019, 07:02 Manuel Carrero [email protected] wrote:

I was wondering if exists some command like delete_edge(), to delete an specific edge row.

I don't know how to create a method to delete edges in django rest framework, using orientdb OGM.

I'm using pyorient==1.5.5 and OrientDB 3.0.18 version.

I have two vertex Classes: ousers, ocompany. Also I have two relationships (edges) Classes: ofriends, oworksat. So for example:

To make a ofriends relationship I need two ousers. And to make a oworksat relationship I need one ouser and one ocompany. Every relationship has it own cluster id.

I know that I can access to these functions:

(Pdb) dir(graph) ['PROPERTY_TYPES', '_GROOVY_GET_DB', '_GROOVY_NULL_LISTENER', '_GROOVY_TRY', 'class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'gt', 'hash', 'init', 'le', 'lt', 'module', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', '_last_cred', '_last_db', 'last_user', 'batch', 'both', 'bothE', 'build_mapping', 'clear_registry', 'client', 'coerce_class_names', 'coerce_class_names_to_quoted', 'compute_all_properties', 'config', 'create_all', 'create_class', 'create_edge', 'create_edge_command', 'create_function', 'create_props_mapping', 'create_vertex', 'create_vertex_command', 'delete_vertex', 'delete_vertex_command', 'drop', 'drop_all', 'drop_class', 'edge_from_record', 'edges_from_records', 'element_from_link', 'element_from_record', 'elements_from_links', 'elements_from_records', 'export', 'get_edge', 'get_element', 'get_vertex', 'gremlin', 'guard_reserved_words', 'inE', 'in', 'include', 'init_broker_for_class', 'list_superclasses', 'ocompany', 'ofriends', 'open', 'ousers', 'out', 'outE', 'oworksat', 'populate', 'property_from_schema', 'props_from_db', 'props_to_db', 'query', 'registry', 'save_element', 'scripts', 'server_version', 'strict', 'toposort_classes', 'valid_element_base', 'vertex_from_record', 'vertexes_from_records']

If I do: graph.delete_vertex("#21:0") It works good and deletes #21 https://github.com/mogui/pyorient/issues/21:0 ouser vertex row, which is part of ofriends and oworskat relationships, so also, that command deletes the relationship where that vertex is included. Obviously, I don't want to delete the entire vertex, just only the specific edge (not the class, just the relationship row).

I was wondering if exists some command like delete_edge(), but dir(graph) don't tell me nothing related.

settings.py

from pyorient.ogm import Graph, Config from pyorient.serializations import OrientSerialization from pyorient.ogm import declarative

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(file)))

config = RawConfigParser() config.read(BASE_DIR + '/settings.ini')

ORIENTDB = { 'NAME': config.get('orientdbConf', 'DB_NAME'), 'USER': config.get('orientdbConf', 'DB_USER'), 'PASSWORD': config.get('orientdbConf', 'DB_PASS'), 'HOST': config.get('orientdbConf', 'DB_HOST'), 'PORT': config.get('orientdbConf', 'DB_PORT'), }

Config.from_url('plocal://'+ORIENTDB['HOST']+':'+str(ORIENTDB['PORT'])+'/'+ORIENTDB['NAME']+'',''+ORIENTDB['USER']+'', ''+ORIENTDB['PASSWORD']+'',initial_drop=False,serialization_type=OrientSerialization.Binary) graph = Graph(Config.from_url(''+ORIENTDB['HOST']+'/'+ORIENTDB['NAME']+'',''+ORIENTDB['USER']+'', ''+ORIENTDB['PASSWORD']+'',initial_drop=False)) Node = declarative.declarative_node() Relationship = declarative.declarative_relationship()

models.py

from core.settings import Node,Relationship,graph from pyorient.ogm.property import (String, Date, DateTime, Decimal, Double, Integer, Boolean, EmbeddedMap, EmbeddedSet,Link, UUID)

class OUsers(Node): element_plural = 'ousers' postgresql_id=Integer(nullable=False,unique=True)

class OCompany(Node): element_plural = 'ocompany' postgresql_id=Integer(nullable=False,unique=True)

class OFriends(Relationship): label = 'ofriends' from_postgresql_ouser_id=Integer(nullable=False,unique=True) to_postgresql_ouser_id=Integer(nullable=False,unique=True)

class OWorksAt(Relationship): label = 'oworksat' from_postgresql_ouser_id=Integer(nullable=False,unique=True) to_postgresql_ocompany_id=Integer(nullable=False,unique=True)

graph.create_all(Node.registry) graph.create_all(Relationship.registry)

serializers.py

from .models import (OUsers,OCompany,OFriends,OWorksAt) from rest_framework import serializers from django.contrib.auth import get_user_model User = get_user_model()

class OFriendsSerializer(serializers.Serializer): from_postgresql_ouser_id = serializers.IntegerField() to_postgresql_ouser_id = serializers.IntegerField()

def create(self, data):
    return OFriends.objects.create(**data)

def update(self, instance, data):
    instance.from_postgresql_ouser_id = data.get("from_postgresql_ouser_id")
    instance.to_postgresql_ouser_id = data.get("to_postgresql_ouser_id")
    instance.save()
    return instance

class OFriendsSerializer(serializers.Serializer): from_postgresql_ouser_id = serializers.IntegerField() to_postgresql_ouser_id = serializers.IntegerField()

def create(self, data):
    return OFriends.objects.create(**data)

def update(self, instance, data):
    instance.from_postgresql_ouser_id = data.get("from_postgresql_ouser_id")
    instance.to_postgresql_ouser_id = data.get("to_postgresql_ouser_id")
    instance.save()
    return instance

api.py

class OFriendsViewSet(viewsets.ModelViewSet):

def destroy(self, request, *args, **kwargs):
    queryset = graph.ofriends.query()
    import pdb;pdb.set_trace()
    # HERE should be the command

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/mogui/pyorient/issues/284?email_source=notifications&email_token=ACYK4O3U7EL2VE3AUFMYUULPZVHUNA5CNFSM4HWMY7W2YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4GYOMSJA, or mute the thread https://github.com/notifications/unsubscribe-auth/ACYK4OYCMXZS5VWWYL33SX3PZVHUNANCNFSM4HWMY7WQ .

TropicalPenguin avatar Jun 09 '19 19:06 TropicalPenguin

Thanks! Is there any plan to add this functionality in a near future?

At the moment, I only could work with raw queries to delete the edge

LegolasVzla avatar Jun 11 '19 04:06 LegolasVzla

At the moment, I solved my problem using pyorient client, with raw query:

pyorient_client.py

from core.settings import ORIENTDB
import pyorient

def orientdbConnection():
	"""Orientdb client connection"""
	client = None
	try:
		client = pyorient.OrientDB(ORIENTDB['HOST'], int(ORIENTDB['PORT']))
		session_id = client.connect( ORIENTDB['USER'], ORIENTDB['PASSWORD'] )
		if client.db_exists( ORIENTDB['NAME'], pyorient.STORAGE_TYPE_MEMORY ):
			client.db_open( ORIENTDB['NAME'], ORIENTDB['USER'], ORIENTDB['PASSWORD'])
	except Exception as e:
		print ("[ ERROR ] Fail orientdb connection. Error: " + str(e))
	return client

And in the api.py

from core.pyorient_client import *

class OFriendsViewSet(viewsets.ModelViewSet):

	def destroy(self, request, *args, **kwargs):
		client = orientdbConnection()
		
		client.command("delete edge ofriends where @rid = '" + kwargs['pk'] + "'")
		
		return Response(status=status.HTTP_204_NO_CONTENT)

Maybe this could be useful for anyone else. Note that I receive o'friends rid as a parameter (by passing the id in DELETE method in swagger UI).

LegolasVzla avatar Jun 16 '19 18:06 LegolasVzla