mirror of
https://github.com/veops/cmdb.git
synced 2025-08-07 16:20:56 +08:00
@@ -182,6 +182,9 @@ class CIManager(object):
|
||||
need_children and res.update(CIRelationManager.get_children(ci_id, ret_key=ret_key)) # one floor
|
||||
|
||||
ci_type = CITypeCache.get(ci.type_id)
|
||||
if not ci_type:
|
||||
return res
|
||||
|
||||
res["ci_type"] = ci_type.name
|
||||
|
||||
fields = CITypeAttributeManager.get_attr_names_by_type_id(ci.type_id) if not fields else fields
|
||||
@@ -518,11 +521,13 @@ class CIManager(object):
|
||||
item.delete(commit=False)
|
||||
|
||||
for item in CIRelation.get_by(first_ci_id=ci_id, to_dict=False):
|
||||
ci_relation_delete.apply_async(args=(item.first_ci_id, item.second_ci_id), queue=CMDB_QUEUE)
|
||||
ci_relation_delete.apply_async(
|
||||
args=(item.first_ci_id, item.second_ci_id, item.ancestor_ids), queue=CMDB_QUEUE)
|
||||
item.delete(commit=False)
|
||||
|
||||
for item in CIRelation.get_by(second_ci_id=ci_id, to_dict=False):
|
||||
ci_relation_delete.apply_async(args=(item.first_ci_id, item.second_ci_id), queue=CMDB_QUEUE)
|
||||
ci_relation_delete.apply_async(
|
||||
args=(item.first_ci_id, item.second_ci_id, item.ancestor_ids), queue=CMDB_QUEUE)
|
||||
item.delete(commit=False)
|
||||
|
||||
ad_ci = AutoDiscoveryCI.get_by(ci_id=ci_id, to_dict=False, first=True)
|
||||
@@ -886,12 +891,14 @@ class CIRelationManager(object):
|
||||
|
||||
@classmethod
|
||||
def get_ancestor_ids(cls, ci_ids, level=1):
|
||||
for _ in range(level):
|
||||
cis = db.session.query(CIRelation.first_ci_id).filter(
|
||||
level2ids = dict()
|
||||
for _level in range(1, level + 1):
|
||||
cis = db.session.query(CIRelation.first_ci_id, CIRelation.ancestor_ids).filter(
|
||||
CIRelation.second_ci_id.in_(ci_ids)).filter(CIRelation.deleted.is_(False))
|
||||
ci_ids = [i.first_ci_id for i in cis]
|
||||
level2ids[_level + 1] = {int(i.ancestor_ids.split(',')[-1]) for i in cis if i.ancestor_ids}
|
||||
|
||||
return ci_ids
|
||||
return ci_ids, level2ids
|
||||
|
||||
@staticmethod
|
||||
def _check_constraint(first_ci_id, first_type_id, second_ci_id, second_type_id, type_relation):
|
||||
@@ -918,13 +925,14 @@ class CIRelationManager(object):
|
||||
return abort(400, ErrFormat.relation_constraint.format("1-N"))
|
||||
|
||||
@classmethod
|
||||
def add(cls, first_ci_id, second_ci_id, more=None, relation_type_id=None):
|
||||
def add(cls, first_ci_id, second_ci_id, more=None, relation_type_id=None, ancestor_ids=None):
|
||||
|
||||
first_ci = CIManager.confirm_ci_existed(first_ci_id)
|
||||
second_ci = CIManager.confirm_ci_existed(second_ci_id)
|
||||
|
||||
existed = CIRelation.get_by(first_ci_id=first_ci_id,
|
||||
second_ci_id=second_ci_id,
|
||||
ancestor_ids=ancestor_ids,
|
||||
to_dict=False,
|
||||
first=True)
|
||||
if existed is not None:
|
||||
@@ -960,11 +968,12 @@ class CIRelationManager(object):
|
||||
|
||||
existed = CIRelation.create(first_ci_id=first_ci_id,
|
||||
second_ci_id=second_ci_id,
|
||||
relation_type_id=relation_type_id)
|
||||
relation_type_id=relation_type_id,
|
||||
ancestor_ids=ancestor_ids)
|
||||
|
||||
CIRelationHistoryManager().add(existed, OperateType.ADD)
|
||||
|
||||
ci_relation_cache.apply_async(args=(first_ci_id, second_ci_id), queue=CMDB_QUEUE)
|
||||
ci_relation_cache.apply_async(args=(first_ci_id, second_ci_id, ancestor_ids), queue=CMDB_QUEUE)
|
||||
|
||||
if more is not None:
|
||||
existed.upadte(more=more)
|
||||
@@ -988,53 +997,56 @@ class CIRelationManager(object):
|
||||
his_manager = CIRelationHistoryManager()
|
||||
his_manager.add(cr, operate_type=OperateType.DELETE)
|
||||
|
||||
ci_relation_delete.apply_async(args=(cr.first_ci_id, cr.second_ci_id), queue=CMDB_QUEUE)
|
||||
ci_relation_delete.apply_async(args=(cr.first_ci_id, cr.second_ci_id, cr.ancestor_ids), queue=CMDB_QUEUE)
|
||||
|
||||
return cr_id
|
||||
|
||||
@classmethod
|
||||
def delete_2(cls, first_ci_id, second_ci_id):
|
||||
def delete_2(cls, first_ci_id, second_ci_id, ancestor_ids=None):
|
||||
cr = CIRelation.get_by(first_ci_id=first_ci_id,
|
||||
second_ci_id=second_ci_id,
|
||||
ancestor_ids=ancestor_ids,
|
||||
to_dict=False,
|
||||
first=True)
|
||||
|
||||
ci_relation_delete.apply_async(args=(first_ci_id, second_ci_id), queue=CMDB_QUEUE)
|
||||
ci_relation_delete.apply_async(args=(first_ci_id, second_ci_id, ancestor_ids), queue=CMDB_QUEUE)
|
||||
|
||||
return cls.delete(cr.id)
|
||||
return cr and cls.delete(cr.id)
|
||||
|
||||
@classmethod
|
||||
def batch_update(cls, ci_ids, parents, children):
|
||||
def batch_update(cls, ci_ids, parents, children, ancestor_ids=None):
|
||||
"""
|
||||
only for many to one
|
||||
:param ci_ids:
|
||||
:param parents:
|
||||
:param children:
|
||||
:param ancestor_ids:
|
||||
:return:
|
||||
"""
|
||||
if isinstance(parents, list):
|
||||
for parent_id in parents:
|
||||
for ci_id in ci_ids:
|
||||
cls.add(parent_id, ci_id)
|
||||
cls.add(parent_id, ci_id, ancestor_ids=ancestor_ids)
|
||||
|
||||
if isinstance(children, list):
|
||||
for child_id in children:
|
||||
for ci_id in ci_ids:
|
||||
cls.add(ci_id, child_id)
|
||||
cls.add(ci_id, child_id, ancestor_ids=ancestor_ids)
|
||||
|
||||
@classmethod
|
||||
def batch_delete(cls, ci_ids, parents):
|
||||
def batch_delete(cls, ci_ids, parents, ancestor_ids=None):
|
||||
"""
|
||||
only for many to one
|
||||
:param ci_ids:
|
||||
:param parents:
|
||||
:param ancestor_ids:
|
||||
:return:
|
||||
"""
|
||||
|
||||
if isinstance(parents, list):
|
||||
for parent_id in parents:
|
||||
for ci_id in ci_ids:
|
||||
cls.delete_2(parent_id, ci_id)
|
||||
cls.delete_2(parent_id, ci_id, ancestor_ids=ancestor_ids)
|
||||
|
||||
|
||||
class CITriggerManager(object):
|
||||
|
@@ -637,6 +637,16 @@ class CITypeRelationManager(object):
|
||||
current_app.logger.warning(str(e))
|
||||
return abort(400, ErrFormat.circular_dependency_error)
|
||||
|
||||
if constraint == ConstraintEnum.Many2Many:
|
||||
other_c = CITypeRelation.get_by(parent_id=p.id, constraint=ConstraintEnum.Many2Many,
|
||||
to_dict=False, first=True)
|
||||
other_p = CITypeRelation.get_by(child_id=c.id, constraint=ConstraintEnum.Many2Many,
|
||||
to_dict=False, first=True)
|
||||
if other_c and other_c.child_id != c.id:
|
||||
return abort(400, ErrFormat.m2m_relation_constraint.format(p.name, other_c.child.name))
|
||||
if other_p and other_p.parent_id != p.id:
|
||||
return abort(400, ErrFormat.m2m_relation_constraint.format(other_p.parent.name, c.name))
|
||||
|
||||
existed = cls._get(p.id, c.id)
|
||||
if existed is not None:
|
||||
existed.update(relation_type_id=relation_type_id,
|
||||
@@ -686,6 +696,24 @@ class CITypeRelationManager(object):
|
||||
|
||||
cls.delete(ctr.id)
|
||||
|
||||
@staticmethod
|
||||
def get_level2constraint(root_id, level):
|
||||
level = level + 1 if level == 1 else level
|
||||
ci = CI.get_by_id(root_id)
|
||||
if ci is None:
|
||||
return dict()
|
||||
|
||||
root_id = ci.type_id
|
||||
level2constraint = dict()
|
||||
for lv in range(1, int(level) + 1):
|
||||
for i in CITypeRelation.get_by(parent_id=root_id, to_dict=False):
|
||||
if i.constraint == ConstraintEnum.Many2Many:
|
||||
root_id = i.child_id
|
||||
level2constraint[lv] = ConstraintEnum.Many2Many
|
||||
break
|
||||
|
||||
return level2constraint
|
||||
|
||||
|
||||
class CITypeAttributeGroupManager(object):
|
||||
cls = CITypeAttributeGroup
|
||||
|
@@ -100,6 +100,7 @@ class AttributeDefaultValueEnum(BaseEnum):
|
||||
CMDB_QUEUE = "one_cmdb_async"
|
||||
REDIS_PREFIX_CI = "ONE_CMDB"
|
||||
REDIS_PREFIX_CI_RELATION = "CMDB_CI_RELATION"
|
||||
REDIS_PREFIX_CI_RELATION2 = "CMDB_CI_RELATION2"
|
||||
|
||||
BUILTIN_KEYWORDS = {'id', '_id', 'ci_id', 'type', '_type', 'ci_type'}
|
||||
|
||||
|
@@ -14,7 +14,10 @@ from api.lib.cmdb.attribute import AttributeManager
|
||||
from api.lib.cmdb.cache import AttributeCache
|
||||
from api.lib.cmdb.cache import CITypeAttributesCache
|
||||
from api.lib.cmdb.cache import CITypeCache
|
||||
from api.lib.cmdb.const import PermEnum, ResourceTypeEnum, RoleEnum
|
||||
from api.lib.cmdb.const import ConstraintEnum
|
||||
from api.lib.cmdb.const import PermEnum
|
||||
from api.lib.cmdb.const import ResourceTypeEnum
|
||||
from api.lib.cmdb.const import RoleEnum
|
||||
from api.lib.cmdb.perms import CIFilterPermsCRUD
|
||||
from api.lib.cmdb.resp_format import ErrFormat
|
||||
from api.lib.exception import AbortException
|
||||
@@ -229,14 +232,28 @@ class PreferenceManager(object):
|
||||
if not parents:
|
||||
return
|
||||
|
||||
for l in leaf:
|
||||
_find_parent(l)
|
||||
for _l in leaf:
|
||||
_find_parent(_l)
|
||||
|
||||
for node_id in node2show_types:
|
||||
node2show_types[node_id] = [CITypeCache.get(i).to_dict() for i in set(node2show_types[node_id])]
|
||||
|
||||
topo_flatten = list(toposort.toposort_flatten(topo))
|
||||
level2constraint = {}
|
||||
for i, _ in enumerate(topo_flatten[1:]):
|
||||
ctr = CITypeRelation.get_by(
|
||||
parent_id=topo_flatten[i], child_id=topo_flatten[i + 1], first=True, to_dict=False)
|
||||
level2constraint[i + 1] = ctr and ctr.constraint
|
||||
|
||||
if leaf2show_types.get(topo_flatten[-1]):
|
||||
ctr = CITypeRelation.get_by(
|
||||
parent_id=topo_flatten[-1],
|
||||
child_id=leaf2show_types[topo_flatten[-1]][0], first=True, to_dict=False)
|
||||
level2constraint[len(topo_flatten)] = ctr and ctr.constraint
|
||||
|
||||
result[view_name] = dict(topo=list(map(list, toposort.toposort(topo))),
|
||||
topo_flatten=list(toposort.toposort_flatten(topo)),
|
||||
topo_flatten=topo_flatten,
|
||||
level2constraint=level2constraint,
|
||||
leaf=leaf,
|
||||
leaf2show_types=leaf2show_types,
|
||||
node2show_types=node2show_types,
|
||||
@@ -338,3 +355,29 @@ class PreferenceManager(object):
|
||||
|
||||
for i in PreferenceTreeView.get_by(type_id=type_id, uid=uid, to_dict=False):
|
||||
i.soft_delete()
|
||||
|
||||
@staticmethod
|
||||
def can_edit_relation(parent_id, child_id):
|
||||
views = PreferenceRelationView.get_by(to_dict=False)
|
||||
for view in views:
|
||||
has_m2m = False
|
||||
last_node_id = None
|
||||
for cr in view.cr_ids:
|
||||
_rel = CITypeRelation.get_by(parent_id=cr['parent_id'], child_id=cr['child_id'],
|
||||
first=True, to_dict=False)
|
||||
if _rel and _rel.constraint == ConstraintEnum.Many2Many:
|
||||
has_m2m = True
|
||||
|
||||
if parent_id == _rel.parent_id and child_id == _rel.child_id:
|
||||
return False
|
||||
|
||||
if _rel:
|
||||
last_node_id = _rel.child_id
|
||||
|
||||
if parent_id == last_node_id:
|
||||
rels = CITypeRelation.get_by(parent_id=last_node_id, to_dict=False)
|
||||
for rel in rels:
|
||||
if rel.child_id == child_id and has_m2m:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
@@ -31,6 +31,7 @@ class ErrFormat(CommonErrFormat):
|
||||
unique_key_required = "主键字段 {} 缺失"
|
||||
ci_is_already_existed = "CI 已经存在!"
|
||||
relation_constraint = "关系约束: {}, 校验失败 "
|
||||
m2m_relation_constraint = "多对多关系 限制: 模型 {} <-> {} 已经存在多对多关系!"
|
||||
relation_not_found = "CI关系: {} 不存在"
|
||||
ci_search_Parentheses_invalid = "搜索表达式里小括号前不支持: 或、非"
|
||||
|
||||
|
@@ -1,6 +1,4 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
import json
|
||||
from collections import Counter
|
||||
|
||||
@@ -10,11 +8,14 @@ from flask import current_app
|
||||
from api.extensions import rd
|
||||
from api.lib.cmdb.ci import CIRelationManager
|
||||
from api.lib.cmdb.ci_type import CITypeRelationManager
|
||||
from api.lib.cmdb.const import ConstraintEnum
|
||||
from api.lib.cmdb.const import REDIS_PREFIX_CI_RELATION
|
||||
from api.lib.cmdb.const import REDIS_PREFIX_CI_RELATION2
|
||||
from api.lib.cmdb.resp_format import ErrFormat
|
||||
from api.lib.cmdb.search.ci.db.search import Search as SearchFromDB
|
||||
from api.lib.cmdb.search.ci.es.search import Search as SearchFromES
|
||||
from api.models.cmdb import CI
|
||||
from api.models.cmdb import CIRelation
|
||||
|
||||
|
||||
class Search(object):
|
||||
@@ -26,7 +27,8 @@ class Search(object):
|
||||
page=1,
|
||||
count=None,
|
||||
sort=None,
|
||||
reverse=False):
|
||||
reverse=False,
|
||||
ancestor_ids=None):
|
||||
self.orig_query = query
|
||||
self.fl = fl
|
||||
self.facet_field = facet_field
|
||||
@@ -38,25 +40,81 @@ class Search(object):
|
||||
self.level = level or 0
|
||||
self.reverse = reverse
|
||||
|
||||
def _get_ids(self):
|
||||
self.level2constraint = CITypeRelationManager.get_level2constraint(
|
||||
root_id[0] if root_id and isinstance(root_id, list) else root_id,
|
||||
level[0] if isinstance(level, list) and level else level)
|
||||
|
||||
self.ancestor_ids = ancestor_ids
|
||||
self.has_m2m = False
|
||||
if self.ancestor_ids:
|
||||
self.has_m2m = True
|
||||
else:
|
||||
level = level[0] if isinstance(level, list) and level else level
|
||||
for _l, c in self.level2constraint.items():
|
||||
if _l < int(level) and c == ConstraintEnum.Many2Many:
|
||||
self.has_m2m = True
|
||||
|
||||
def _get_ids(self, ids):
|
||||
if self.level[-1] == 1 and len(ids) == 1:
|
||||
if self.ancestor_ids is None:
|
||||
return [i.second_ci_id for i in CIRelation.get_by(first_ci_id=ids[0], to_dict=False)]
|
||||
|
||||
else:
|
||||
seconds = {i.second_ci_id for i in CIRelation.get_by(first_ci_id=ids[0],
|
||||
ancestor_ids=self.ancestor_ids,
|
||||
to_dict=False)}
|
||||
|
||||
return list(seconds)
|
||||
|
||||
merge_ids = []
|
||||
ids = [self.root_id] if not isinstance(self.root_id, list) else self.root_id
|
||||
key = []
|
||||
_tmp = []
|
||||
for level in range(1, sorted(self.level)[-1] + 1):
|
||||
_tmp = list(map(lambda x: list(json.loads(x).keys()),
|
||||
filter(lambda x: x is not None, rd.get(ids, REDIS_PREFIX_CI_RELATION) or [])))
|
||||
if not self.has_m2m:
|
||||
_tmp = map(lambda x: json.loads(x).keys(),
|
||||
filter(lambda x: x is not None, rd.get(ids, REDIS_PREFIX_CI_RELATION) or []))
|
||||
ids = [j for i in _tmp for j in i]
|
||||
key, prefix = ids, REDIS_PREFIX_CI_RELATION
|
||||
|
||||
else:
|
||||
if not self.ancestor_ids:
|
||||
if level == 1:
|
||||
key, prefix = list(map(str, ids)), REDIS_PREFIX_CI_RELATION
|
||||
else:
|
||||
key = list(set(["{},{}".format(i, j) for idx, i in enumerate(key) for j in _tmp[idx]]))
|
||||
prefix = REDIS_PREFIX_CI_RELATION2
|
||||
else:
|
||||
if level == 1:
|
||||
key, prefix = ["{},{}".format(self.ancestor_ids, i) for i in ids], REDIS_PREFIX_CI_RELATION2
|
||||
else:
|
||||
key = list(set(["{},{}".format(i, j) for idx, i in enumerate(key) for j in _tmp[idx]]))
|
||||
prefix = REDIS_PREFIX_CI_RELATION2
|
||||
|
||||
if not key:
|
||||
return []
|
||||
|
||||
_tmp = list(map(lambda x: json.loads(x).keys() if x else [], rd.get(key, prefix) or []))
|
||||
ids = [j for i in _tmp for j in i]
|
||||
|
||||
if level in self.level:
|
||||
merge_ids.extend(ids)
|
||||
|
||||
return merge_ids
|
||||
|
||||
def _get_reverse_ids(self):
|
||||
def _get_reverse_ids(self, ids):
|
||||
merge_ids = []
|
||||
ids = [self.root_id] if not isinstance(self.root_id, list) else self.root_id
|
||||
level2ids = {}
|
||||
for level in range(1, sorted(self.level)[-1] + 1):
|
||||
ids = CIRelationManager.get_ancestor_ids(ids, 1)
|
||||
ids, _level2ids = CIRelationManager.get_ancestor_ids(ids, 1)
|
||||
|
||||
if _level2ids.get(2):
|
||||
level2ids[level + 1] = _level2ids[2]
|
||||
|
||||
if level in self.level:
|
||||
merge_ids.extend(ids)
|
||||
if level in level2ids and level2ids[level]:
|
||||
merge_ids.extend(set(ids) & set(level2ids[level]))
|
||||
else:
|
||||
merge_ids.extend(ids)
|
||||
|
||||
return merge_ids
|
||||
|
||||
@@ -64,7 +122,7 @@ class Search(object):
|
||||
ids = [self.root_id] if not isinstance(self.root_id, list) else self.root_id
|
||||
cis = [CI.get_by_id(_id) or abort(404, ErrFormat.ci_not_found.format("id={}".format(_id))) for _id in ids]
|
||||
|
||||
merge_ids = self._get_ids() if not self.reverse else self._get_reverse_ids()
|
||||
merge_ids = self._get_ids(ids) if not self.reverse else self._get_reverse_ids(ids)
|
||||
|
||||
if not self.orig_query or ("_type:" not in self.orig_query
|
||||
and "type_id:" not in self.orig_query
|
||||
@@ -76,11 +134,11 @@ class Search(object):
|
||||
type_ids.extend(CITypeRelationManager.get_child_type_ids(ci.type_id, level))
|
||||
else:
|
||||
type_ids.extend(CITypeRelationManager.get_parent_type_ids(ci.type_id, level))
|
||||
type_ids = list(set(type_ids))
|
||||
type_ids = set(type_ids)
|
||||
if self.orig_query:
|
||||
self.orig_query = "_type:({0}),{1}".format(";".join(list(map(str, type_ids))), self.orig_query)
|
||||
self.orig_query = "_type:({0}),{1}".format(";".join(map(str, type_ids)), self.orig_query)
|
||||
else:
|
||||
self.orig_query = "_type:({0})".format(";".join(list(map(str, type_ids))))
|
||||
self.orig_query = "_type:({0})".format(";".join(map(str, type_ids)))
|
||||
|
||||
if not merge_ids:
|
||||
# cis, counter, total, self.page, numfound, facet_
|
||||
@@ -105,35 +163,65 @@ class Search(object):
|
||||
|
||||
def statistics(self, type_ids):
|
||||
self.level = int(self.level)
|
||||
_tmp = []
|
||||
|
||||
ids = [self.root_id] if not isinstance(self.root_id, list) else self.root_id
|
||||
for lv in range(0, self.level):
|
||||
if not lv:
|
||||
if type_ids and lv == self.level - 1:
|
||||
_tmp = []
|
||||
level2ids = {}
|
||||
for lv in range(1, self.level + 1):
|
||||
level2ids[lv] = []
|
||||
|
||||
if lv == 1:
|
||||
if not self.has_m2m:
|
||||
key, prefix = ids, REDIS_PREFIX_CI_RELATION
|
||||
else:
|
||||
if not self.ancestor_ids:
|
||||
key, prefix = ids, REDIS_PREFIX_CI_RELATION
|
||||
else:
|
||||
key = ["{},{}".format(self.ancestor_ids, _id) for _id in ids]
|
||||
prefix = REDIS_PREFIX_CI_RELATION2
|
||||
|
||||
level2ids[lv] = [[i] for i in key]
|
||||
|
||||
if not key:
|
||||
_tmp = []
|
||||
continue
|
||||
|
||||
if type_ids and lv == self.level:
|
||||
_tmp = list(map(lambda x: [i for i in x if i[1] in type_ids],
|
||||
(map(lambda x: list(json.loads(x).items()),
|
||||
[i or '{}' for i in rd.get(ids, REDIS_PREFIX_CI_RELATION) or []]))))
|
||||
[i or '{}' for i in rd.get(key, prefix) or []]))))
|
||||
else:
|
||||
_tmp = list(map(lambda x: list(json.loads(x).items()),
|
||||
[i or '{}' for i in rd.get(ids, REDIS_PREFIX_CI_RELATION) or []]))
|
||||
[i or '{}' for i in rd.get(key, prefix) or []]))
|
||||
|
||||
else:
|
||||
for idx, item in enumerate(_tmp):
|
||||
if item:
|
||||
if type_ids and lv == self.level - 1:
|
||||
__tmp = list(
|
||||
map(lambda x: [(_id, type_id) for _id, type_id in json.loads(x).items()
|
||||
if type_id in type_ids],
|
||||
filter(lambda x: x is not None,
|
||||
rd.get([i[0] for i in item], REDIS_PREFIX_CI_RELATION) or [])))
|
||||
if not self.has_m2m:
|
||||
key, prefix = [i[0] for i in item], REDIS_PREFIX_CI_RELATION
|
||||
else:
|
||||
key = list(set(['{},{}'.format(j, i[0]) for i in item for j in level2ids[lv - 1][idx]]))
|
||||
prefix = REDIS_PREFIX_CI_RELATION2
|
||||
|
||||
__tmp = list(map(lambda x: list(json.loads(x).items()),
|
||||
filter(lambda x: x is not None,
|
||||
rd.get([i[0] for i in item], REDIS_PREFIX_CI_RELATION) or [])))
|
||||
level2ids[lv].append(key)
|
||||
|
||||
if key:
|
||||
if type_ids and lv == self.level:
|
||||
__tmp = map(lambda x: [(_id, type_id) for _id, type_id in json.loads(x).items()
|
||||
if type_id in type_ids],
|
||||
filter(lambda x: x is not None,
|
||||
rd.get(key, prefix) or []))
|
||||
else:
|
||||
__tmp = map(lambda x: list(json.loads(x).items()),
|
||||
filter(lambda x: x is not None,
|
||||
rd.get(key, prefix) or []))
|
||||
else:
|
||||
__tmp = []
|
||||
|
||||
_tmp[idx] = [j for i in __tmp for j in i]
|
||||
else:
|
||||
_tmp[idx] = []
|
||||
level2ids[lv].append([])
|
||||
|
||||
result = {str(_id): len(_tmp[idx]) for idx, _id in enumerate(ids)}
|
||||
|
||||
|
Reference in New Issue
Block a user