代码极思精致的瞬间(其二)

一 数据库插入数据 进行类型 转换
1,influxdb 数据库表名 转换成 postgresql 数据库表名称
2,influxdb 数据库字段类型转化!
fpga_type_mapping={
    'node_fpga_type':str,
    'node_fpga_errors':int
}

fpga_field_mapping={
    'node_fpga_type':'type',
    'node_fpga_errors':'errors',
}


@shared_task(ignore_result=True)
def node_fpga_summaries():
    results = cache.get(_FPGA_SQL)
    fpga_caches = dict()
    for result in results:
        for k, v in result.items():
            host = k[1]["host"]
            field = k[0]
            for item in v:
                index = int( item['index'])
                # influx 数据库表名 转换成 postgresql 数据库表名称
                val = fpga_type_mapping[field](item['value'])
                fpga_caches[host] = fpgas = fpga_caches.get( host, dict())
                fpgas[index] = fpgas = fpgas.get( index, dict())
                # 字段类型转化!
                fpgas.update( {fpga_field_mapping[field]: val})
    try:
        with transaction.atomic():
            update_ids = []
            for k_host, v_fpgas in fpga_caches.iteritems():
                try:
                    node = Node.objects.get(hostname=k_host)
                except Node.DoesNotExist:
                    continue
                for k_idx, v_fpga in v_fpgas.iteritems():
                    fpga, ret = node.fpga.update_or_create(
                        index=k_idx,
                        defaults=v_fpga
                    )
                    update_ids.append(fpga.id)
            Fpga.objects.exclude(id__in=update_ids).delete()
    except IntegrityError:
        logger.exception("Failed for node Fpga summaries")
View Code
二,显示节点的所有信息:
1,前端 args 指定字段类型 后台根据类型进行查找
2,很方便的查询到 外键字段 具有高扩展性!
class NodeBase(object):
    columns_mapping = {}

    def get_range(self, *args, **kwargs):
        return Node.objects.all()

    def get_node_status_preference(self, user):
        logger.info("Get preference for node status")
        name = "monitor.policy.node.status"
        try:
            preference = Preference.objects.get(name=name)
        except Preference.DoesNotExist as e:
            logger.exception('Preference name %s does not exist', name)
            raise_from(CheckPreferenceException, e)
        else:
            if preference.user in [None, user]:
                # 'cpu_core' or 'cpu_util' for value
                return preference.value
            else:
                return "cpu_util"

    def convert_cpu_status(self, preference, cpu_util, node_id):
        if preference == "cpu_util":
            util = int(cpu_util)
            if util < IDLE_THRESHOLD:
                return "idle"
            elif util > BUSY_THRESHOLD:
                return "busy"
            else:
                return "used"
        else:
            if RunningJob.objects.filter(node__id=node_id).count() > 0:
                return "busy"
            else:
                return "idle"

    def search(self, query, argss):
        if 'search' not in argss:
            return query
        else:
            search = argss['search']
            props = search['props']
            keyword = search['keyword'].strip()
            if keyword == "":
                return query

            q = Q()
            for field in props:
                prop = field
                if field in self.columns_mapping:
                    prop = self.columns_mapping[field]
                q |= Q(**{prop + "__icontains": keyword})

            return query.filter(q)

    def sort_fields(self, argss):
        if 'sort' not in argss:
            return ['id'], True
        order = argss["sort"]
        prop = order['prop']
        if prop in self.columns_mapping:
            prop = self.columns_mapping[order['prop']]
        if order['order'] != "ascending":
            prop = "-" + prop
        return prop
    # 字段排序!
    def sort(self, query, argss):
        return query.order_by(self.sort_fields(argss))
    # 字段 过滤!
    def filters(self, query, filters):

        if len(filters) > 0 and filters is not None:
            for field in filters:
                if field['prop'] in self.columns_mapping:
                    prop = self.columns_mapping[field['prop']]
                else:
                    prop = field['prop']

                if len(field["values"]) > 0:
                    key = prop + "__{}".format(field["type"])
                    query = query.filter(
                        **{
                            key: field["values"]
                        }
                    )
        return query

    def params(self, args):
        return args


class NodeList(NodeBase, APIView):
    permission_classes = (AsUserRole,)

    columns_mapping = {
        "status": "cpu_util",
        "groups": "groups__name"
    }

    def get(self, request):
        argss = json.loads(
            request.GET["args"]
        )

        argss = self.params(argss)

        query = self.get_range()
        # 根据 args中 filters 指定的字段进行过滤!
        query = self.filters(query, argss['filters'])
        # 根据字段进行查找
        query = self.search(query, argss)
        # 根据指定的字段进行排序!
        query = self.sort(query, argss)
        # 根据指定的数量进行返回数据!如果指定的个数多的话 按照最大进行返回
        # 如果小于 那么就按照指定的数量进行返回!
        filtered_total = query.count()
        offset = argss['offset'] \
            if int(argss['offset']) < filtered_total else 0
        results = query[offset:offset + int(argss['length'])]
        offset = offset + len(results)

        preference = self.get_node_status_preference(request.user)

        return Response(
            {
                'offset': offset,
                'total': filtered_total,
                'data': [self.trans_result(result, preference)
                         for result in results],
            }
        )
    # 可以根据外键进行 查找其他 返回!
    def trans_result(self, result, preference):
        groups = []
        for grp in result.groups.iterator():
            groups.append(grp.name)

        if result.gpu:
            gpus = result.gpu.all()
            gpu_cnt = gpus.count()
            gpu_used = [0] * gpu_cnt
            gpu_type = [""] * gpu_cnt
            for gpu in gpus:
                gpu_used[gpu.index] = int(gpu.occupation)
                gpu_type[gpu.index] = gpu.type
        else:
            gpu_used = []
            gpu_type = []

        if result.fpga:
            fpgas = result.fpga.all()
            fpga_cnt = fpgas.count()
            fpga_type = [""] * fpga_cnt
            for fpga in fpgas:
                fpga_type[fpga.index] = fpga.type
        else:
            fpga_type = []

        power_status = status = "off"
        if result.power_status is True:
            power_status = "on"
            status = self.convert_cpu_status(
                preference,
                result.cpu_util,
                result.id
            )

        return {
            "id": result.id,
            "hostname": result.hostname,
            "bmc_ipv4": result.bmc_ipv4,
            "disk_total": int(result.disk_total),
            "memory_total": int(result.memory_total),
            "mgt_ipv4": result.mgt_ipv4,
            "type": result.type,
            "processors_total": result.cpu_total,
            "power_status": power_status,
            "groups": ",".join(groups),
            "status": status,
            "gpus": {
                "used": gpu_used,
                "type": gpu_type
            },
            "fpgas": {
                "type": fpga_type,
            }
        }
View Code

 

posted @ 2018-11-08 14:47  十七楼的羊  阅读(142)  评论(0编辑  收藏  举报