我简单使用python封装一下CRUD,大家一起来改bug吧
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File : NebulaTools.py
# @Date : 2023/2/1 13:04:46
from nebula3.Config import Config, SessionPoolConfig
from nebula3.gclient.net.SessionPool import SessionPool
from constructionJson.FormatResp import print_resp
import logging
# 配置时间
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s [ %(message)s ]')
import time
class BaseNetWorkNebula(object):
def __init__(self, addresses=[("127.0.0.1", 9669)], user="root", password="nebula", space=None, pool_size=5,
idle_time=2000):
configs = SessionPoolConfig()
configs.min_size = 2
configs.max_size = 5
configs.interval_check = 2
configs.idle_time = idle_time
self.session_pool = SessionPool(user, password, space, addresses)
assert self.session_pool.init(configs)
self.session_pool.execute("USE {}".format(space))
def get_session_pool(self):
"""
获取会话
"""
return self.session_pool
def execute(self, stmt):
"""
执行语句
"""
logging.info(stmt)
# 记录开始时间
start_time = time.time()
resp = self.session_pool.execute(stmt)
if not resp.is_succeeded():
logging.error(resp.error_msg())
return False
logging.info("执行时间:{}s".format(time.time() - start_time))
return resp
def execute_json(self, stmt):
"""
执行语句并返回json格式
"""
return self.session_pool.execute_json(stmt)
def insert_vertex(self, vid, tag, props):
"""
插入点
insert_vertex("player127", "player", {'age': 221122})
@param vid: 点id
@param tag: 标签点类型
@param props: 属性
"""
# 判断vid的类型
if isinstance(vid, str):
vid = "'{}'".format(vid)
stmt = "INSERT VERTEX {}({}) VALUES {}:{}"
keys = []
for key, value in props.items():
# 判断是否有None
if value is None:
props[key] = 'NULL'
keys.append(key)
tagProfile = ",".join(keys)
values = str(tuple(props.values())).replace("'NULL'", "NULL")
stmt = stmt.format(tag, tagProfile, vid, values)
# 只有一个值的时候,不需要加上逗号
if len(props) == 1:
stmt = stmt.replace(",)", ")")
return self.execute(stmt)
def insert_edge(self, src_vid, dst_vid, edge, props, rank=None):
"""
插入边
insert_edge("player127", "player148", "follow", {'degree': 555}, 2)
@param src_vid: 起始点id
@param dst_vid: 目标点id
@param edge: 边类型
@param props: 属性
@param rank: 权重 默认为0
"""
if isinstance(src_vid, str):
src_vid = "'{}'".format(src_vid)
if isinstance(dst_vid, str):
dst_vid = "'{}'".format(dst_vid)
if rank:
stmt = "INSERT EDGE {}({}) VALUES {}->{}@{}:{}"
else:
stmt = "INSERT EDGE {}({}) VALUES {}->{}:{}"
keys = []
for key, value in props.items():
# 判断是否有None
if value is None:
props[key] = 'NULL'
keys.append(key)
tagProfile = ",".join(keys)
values = str(tuple(props.values())).replace("'NULL'", "NULL")
if rank:
stmt = stmt.format(edge, ",".join(keys), src_vid, dst_vid, rank, values)
else:
stmt = stmt.format(edge, ",".join(keys), src_vid, dst_vid, values)
# 只有一个值的时候,不需要加上逗号
if len(props) == 1:
stmt = stmt.replace(",)", ")")
print(stmt)
return self.execute(stmt)
def update_vertex(self, vid, tag, props, WHEN=None):
"""
更新点
update_vertex("player127", "player", {'age': 221122, "name": "xiaoming"}, {"name": "xiaoming", "age": 21122})
@param vid: 点id
@param tag: 标签点类型
@param props: 属性
@param WHEN: 条件
@return: 修改成功返回修改结果,未修改返回原数据 取决于WHEN条件是否成立
"""
if isinstance(vid, str):
vid = "'{}'".format(vid)
for key, value in props.items():
if isinstance(value, str):
props[key] = "'{}'".format(value)
if value is None:
props[key] = 'NULL'
setStr = ", ".join(
["{} = {}".format(key, value) for key, value in
props.items()]
)
YIELDStr = ", ".join("{} AS {}".format(key, key) for key, value in
props.items())
if WHEN:
for key, value in WHEN.items():
if isinstance(value, str):
WHEN[key] = "'{}'".format(value)
if value is None:
WHEN[key] = 'NULL'
WHENStr = " AND ".join(
["{} == {}".format(key, value) for key, value in
WHEN.items()]
)
stmt = "UPDATE VERTEX ON {} {} SET {} WHEN {} YIELD {} ;" \
.format(tag, vid, setStr, WHENStr, YIELDStr)
else:
stmt = "UPDATE VERTEX ON {} {} SET {} YIELD {} ;" \
.format(tag, vid, setStr, YIELDStr)
print(stmt)
return self.execute(stmt)
def update_edge(self, src_vid, dst_vid, edge, props, WHEN=None, rank=0):
"""
update_edge("player127", "player148x", "follow", {'degree': 555},WHEN={"degree": "555"}, rank=2)
@param src_vid: 起始点id
@param dst_vid: 目标点id
@param edge: 边类型
@param props: 属性
@param WHEN: 条件
@param rank: 权重 默认为0
@return: 修改成功返回修改结果,未修改返回原数据 取决于WHEN条件是否成立
"""
if isinstance(src_vid, str):
src = "'{}'".format(src_vid)
if isinstance(dst_vid, str):
dst = "'{}'".format(dst_vid)
for key, value in props.items():
if isinstance(value, str):
props[key] = "'{}'".format(value)
if value is None:
props[key] = 'NULL'
setStr = ", ".join(
["{} = {}".format(key, value) for key, value in
props.items()]
)
YIELDStr = ", ".join("{} AS {}".format(key, key) for key, value in
props.items())
if WHEN:
for key, value in WHEN.items():
if isinstance(value, str):
WHEN[key] = "'{}'".format(value)
if value is None:
WHEN[key] = 'NULL'
WHENStr = " AND ".join(
["{} == {}".format(key, value) for key, value in
WHEN.items()]
)
stmt = "UPDATE EDGE ON {} {}->{}@{} SET {} WHEN {} YIELD {} ;" \
.format(edge, src, dst, rank, setStr, WHENStr, YIELDStr)
else:
stmt = "UPDATE EDGE ON {} {}->{}@{} SET {} YIELD {} ;" \
.format(edge, src, dst, rank, setStr, YIELDStr)
print(stmt)
return self.execute(stmt)
def delete_vertex(self, vid, WITH=False):
"""
删除点
delete_vertex("player148x")
@param vid: 点id
@param WITH: 是否删除该点关联的出边和入边
@return:
"""
if isinstance(vid, str):
vid = "'{}'".format(vid)
if WITH:
stmt = "DELETE VERTEX {} WITH EDGE;".format(vid)
else:
stmt = "DELETE VERTEX {};".format(vid)
return self.execute(stmt)
def delete_vertex_many(self, vids, WITH=False):
"""
批量删除点
delete_vertex_many(["player148x", 222])
@param vids: 点id列表
@param WITH: 是否删除该点关联的出边和入边
@return:
"""
# DELETE VERTEX "player111", "team203",222;
visStr = tuple(vids)
# 去掉两边括号
visStr = str(visStr)[1:-1]
if WITH:
stmt = "DELETE VERTEX {} WITH EDGE;".format(visStr)
else:
stmt = "DELETE VERTEX {};".format(visStr)
return self.execute(stmt)
def delete_edge(self, src_vid, dst_vid, edge, rank=0):
"""
删除边
delete_edge("player127", "player148x", "follow", 2)
@param src_vid: 起始点id
@param dst_vid: 目标点id
@param edge: 边类型
@param rank: 权重 默认为0
@return:
"""
if isinstance(src_vid, str):
src_vid = "'{}'".format(src_vid)
if isinstance(dst_vid, str):
dst_vid = "'{}'".format(dst_vid)
if rank:
stmt = "DELETE EDGE {} {} -> {}@{};".format(edge, src_vid, dst_vid, rank)
else:
stmt = "DELETE EDGE {} {} -> {};".format(edge, src_vid, dst_vid)
print(stmt)
return self.execute(stmt)
def select_vertex(self, tag, vid):
"""
查询点
select_vertex("player", "player127")
@param tag: * 表示当前图空间中的所有 Tag。
@param vid: 点id
@return:
"""
if isinstance(vid, str):
vid = "'{}'".format(vid)
stmt = "FETCH PROP ON {} {} YIELD properties(vertex) AS vx".format(tag, vid)
return self.execute(stmt)
def select_vertex_many(self, tag, vids):
"""
批量查询点
select_vertex_many("player", ["player127", "player148"])
@param tag: * 表示当前图空间中的所有 Tag。
@param vids: 点id列表
@return:
"""
visStr = tuple(vids)
# 去掉两边括号
visStr = str(visStr)[1:-1]
stmt = "FETCH PROP ON {} {} YIELD properties(vertex) AS vx".format(tag, visStr)
print(stmt)
return self.execute(stmt)
def select_edge(self, edge, src_vid, dst_vid, YIELD=None):
"""
查询边
select_edge("follow", "player127", "player148", "properties(edge).degree as degree")
@param edge: * 表示当前图空间中的所有 Edge。
@param src_vid: 起始点id
@param dst_vid: 目标点id
@param YIELD: 自定义方法 例如:YIELD $^.player.name, $$.team.name as teamName
@return:
"""
if isinstance(src_vid, str):
src_vid = "'{}'".format(src_vid)
if isinstance(dst_vid, str):
dst_vid = "'{}'".format(dst_vid)
stmt = "FETCH PROP ON {} {} -> {} YIELD properties(edge) AS ed".format(edge, src_vid, dst_vid)
if YIELD:
stmt = "FETCH PROP ON {} {} -> {} YIELD {}".format(edge, src_vid, dst_vid, YIELD)
return self.execute(stmt)
if __name__ == '__main__':
CONSTANT_HOST = [("127.0.0.1", 9669)]
bn = BaseNetWorkNebula(CONSTANT_HOST, password="password", space="demo_basketballplayer")
# 查询数据
session = bn.get_session_pool()
resp = session.execute('MATCH (v) return v limit 10;')
# print_resp(resp)
# 插入点
resp = bn.insert_vertex("player148x", "player", {'age': 123, 'name': None, '1name': None})
# 插入边
# resp = bn. insert_edge("player127", "player148x", "follow", {'degree': 555}, 2)
# 更新点
# resp = bn.update_vertex("player127", "player", {'age': 221122, "name": "xiaoming"}, {"name": "xxxx", "age": 21122})
# 更新边
# resp = bn.update_edge("player127", "player148x", "follow", {'degree': None},
# {"degree": 1555}, 2)
# 删除点
# resp = bn.delete_vertex("player148x")
# resp = bn.delete_vertex_many(["player148x", "222"])
# 删除边
# resp = bn.delete_edge("player127", "player148x", "follow", 2)
# 查询点
# resp = bn.select_vertex("player", "player127")
# resp = bn.select_vertex_many("player", ["player127", "player148"])
# 查询边
# resp = bn.select_edge("follow", "player127", "player148", "properties(edge).degree as degree")
print(resp)