python 简单封装CRUD

我简单使用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)

3 个赞

idle_time和interval_check的单位都是秒吗?

应该是的,按照文档的配置中的单位