facet query fix

This commit is contained in:
pycook 2016-04-12 13:54:09 +08:00
parent f515988dbd
commit b2f0afd73d
11 changed files with 102 additions and 23 deletions

View File

@ -32,7 +32,7 @@ MODULES = (
(core.ci, "/api/v0.1/ci"),
(core.history, "/api/v0.1/history"),
(core.account, "/api/v0.1/accounts"),
# (core.special, ""),
(core.special, ""),
)

View File

@ -8,4 +8,4 @@ from ci_relation import cirelation
from ci import ci
from history import history
from account import account
# from special import special
from special import special

View File

@ -102,15 +102,21 @@ def delete_attribute(attr_id=None):
@attribute.route("/citype/<int:type_id>", methods=["GET"])
def get_attributes_by_type(type_id=None):
@attribute.route("/citype/<string:type_name>", methods=["GET"])
def get_attributes_by_type(type_id=None, type_name=None):
manager = CITypeAttributeManager()
from models.attribute import CIAttributeCache
from models.ci_type import CITypeCache
from models.ci_type import CITypeAttributeCache
t = CITypeCache.get(type_id)
if not t:
return abort(400, "CIType {0} is not existed".format(type_id))
t = CITypeCache.get(type_name)
if not t:
return abort(400, "CIType {0} is not existed".format(type_id))
type_id = t.type_id
uniq_id = t.uniq_id
CITypeAttributeCache.clean(type_id)
unique = CIAttributeCache.get(uniq_id).attr_name
return jsonify(attributes=manager.get_attributes_by_type_id(type_id),
type_id=type_id, uniq_id=uniq_id, unique=unique)

View File

@ -16,6 +16,7 @@ from flask import abort
from lib.auth import auth_with_key
from lib.ci import CIManager
from lib.ci import HostNumStatis
from lib.search import Search
from lib.search import SearchError
from lib.utils import get_page
@ -156,6 +157,14 @@ def update_ci():
return jsonify(ci_id=ci_id)
@ci.route("/<int:ci_id>/unique", methods=["PUT"])
@auth_with_key
def update_ci_unique(ci_id):
m = CIManager()
m.update_unique_value(ci_id, request.values)
return jsonify(ci_id=ci_id)
@ci.route("/<int:ci_id>", methods=["DELETE"])
@auth_with_key
def delete_ci(ci_id=None):
@ -187,3 +196,21 @@ def get_heartbeat():
ci_type,
agent_status=agent_status)
return jsonify(numfound=numfound, result=result)
######################### just for frontend ###################################
@ci.route("/hosts/nums", methods=["GET"])
def get_hosts_nums():
ci_type = request.args.get("ci_type", "").strip()
ci_ids = request.args.get("ci_ids", "").strip()
ci_id_list = ci_ids.split(",")
ci_id_list = map(str, filter(lambda x: x != "", ci_id_list))
res = {}
if ci_type == "bu":
res = HostNumStatis().get_hosts_by_bu(ci_id_list)
elif ci_type == "product":
res = HostNumStatis().get_hosts_by_product(ci_id_list)
elif ci_type == "project":
res = HostNumStatis().get_hosts_by_project(ci_id_list)
return jsonify(hosts=res)

View File

@ -18,10 +18,10 @@ from models.account import UserCache
def auth_with_key(func):
@wraps(func)
def wrapper(*args, **kwargs):
if isinstance(getattr(g, 'user', None), User):
identity_changed.send(current_app._get_current_object(),
identity=Identity(g.user.uid))
return func(*args, **kwargs)
# if isinstance(getattr(g, 'user', None), User):
# identity_changed.send(current_app._get_current_object(),
# identity=Identity(g.user.uid))
# return func(*args, **kwargs)
ip = request.remote_addr
if request.data:
request_args = dict()
@ -46,7 +46,7 @@ def auth_with_key(func):
else:
identity_changed.send(current_app._get_current_object(),
identity=AnonymousIdentity())
return abort(400, "invalid _key and _secret")
return abort(401, "invalid _key and _secret")
path = request.path
@ -63,6 +63,6 @@ def auth_with_key(func):
else:
identity_changed.send(current_app._get_current_object(),
identity=AnonymousIdentity())
return abort(400, "invalid _key and _secret")
return abort(401, "invalid _key and _secret")
return wrapper

View File

@ -140,16 +140,16 @@ class CIManager(object):
abort(404, "CIType {0} is not existed".format(ci_type_name))
unique_key = CIAttributeCache.get(ci_type.uniq_id) \
or abort(500, 'illegality unique attribute')
or abort(400, 'illegality unique attribute')
unique = ci_dict.get(unique_key.attr_name) \
or abort(500, '{0} missing'.format(unique_key.attr_name))
or abort(400, '{0} missing'.format(unique_key.attr_name))
old_ci = self.ci_is_exist(ci_type, unique_key, unique)
if old_ci is not None:
ci_existed = True
if exist_policy == 'reject':
return abort(500, 'CI is existed')
return abort(400, 'CI is existed')
if old_ci.type_id != ci_type.type_id: # update ci_type
old_ci.type_id = ci_type.type_id
db.session.add(old_ci)
@ -169,7 +169,7 @@ class CIManager(object):
except Exception as e:
db.session.rollback()
current_app.logger.error('add CI error: {0}'.format(str(e)))
return abort(500, 'add CI error')
return abort(400, 'add CI error')
value_manager = AttributeValueManager()
histories = list()
for p, v in ci_dict.items():
@ -182,7 +182,7 @@ class CIManager(object):
if not ci_existed:
self.delete(ci.ci_id)
current_app.logger.info(res)
return abort(500, res)
return abort(400, res)
if res is not None:
histories.append(res)
try:
@ -192,12 +192,39 @@ class CIManager(object):
db.session.rollback()
if not ci_existed: # only add
self.delete(ci.ci_id)
return abort(500, "add CI error")
return abort(400, "add CI error")
his_manager = CIAttributeHistoryManger()
his_manager.add(ci.ci_id, histories)
ci_cache.apply_async([ci.ci_id], queue="cmdb_async")
return ci.ci_id
def update_unique_value(self, ci_id, args):
ci = self.get_ci_by_id(ci_id, need_children=False)
unique_key = ci.get("unique")
attr = CIAttributeCache.get(unique_key)
table_key = "index_{0}".format(attr.value_type) \
if attr.is_index else attr.value_type
value_table = type_map.get("table").get(table_key)
v = args.get(unique_key)
if value_table and v:
item = db.session.query(value_table).filter(
value_table.ci_id == ci_id).filter(
value_table.attr_id == attr.attr_id).first()
if item:
converter = type_map.get("converter").get(attr.value_type)
try:
item.value = converter(v)
except:
return abort(400, "value is illegal")
db.session.add(item)
try:
db.session.commit()
except Exception as e:
db.session.rollback()
current_app.logger.error(str(e))
return abort(400, "update unique failed")
ci_cache.apply_async([ci_id], queue="cmdb_async")
def delete(self, ci_id):
ci = db.session.query(CI).filter(CI.ci_id == ci_id).first()
if ci is not None:
@ -224,7 +251,7 @@ class CIManager(object):
except Exception as e:
db.session.rollback()
current_app.logger.error("delete CI error, {0}".format(str(e)))
return abort(500, "delete CI error, {0}".format(str(e)))
return abort(400, "delete CI error, {0}".format(str(e)))
# TODO: write history
ci_delete.apply_async([ci.ci_id], queue="cmdb_async")
return ci_id
@ -485,7 +512,7 @@ class CIRelationManager(object):
db.session.rollback()
current_app.logger.error("add CIRelation is error, {0}".format(
str(e)))
return abort(500, "add CIRelation is error, {0}".format(str(e)))
return abort(400, "add CIRelation is error, {0}".format(str(e)))
# write history
his_manager = CIRelationHistoryManager()
his_manager.add(cr.cr_id, cr.first_ci_id, cr.second_ci_id,
@ -507,7 +534,7 @@ class CIRelationManager(object):
current_app.logger.error(
"delete CIRelation is error, {0}".format(str(e)))
return abort(
500, "delete CIRelation is error, {0}".format(str(e)))
400, "delete CIRelation is error, {0}".format(str(e)))
his_manager = CIRelationHistoryManager()
his_manager.add(cr_id, first_ci, second_ci,
cr.relation_type, operate_type="delete")

View File

@ -30,6 +30,7 @@ class CITypeAttributeManager(object):
for attr in attrs:
attr_dict = attr_manager.get_attribute_by_id(attr.attr_id)
attr_dict["is_required"] = attr.is_required
attr_dict["order"] = attr.order
result.append(attr_dict)
return result

View File

@ -88,9 +88,9 @@ FACET_QUERY = """
SELECT {0}.value,
count({0}.ci_id)
FROM {0}
INNER JOIN ({1}) AS B ON B.ci_id={0}.ci_id
INNER JOIN ({1}) AS F ON F.ci_id={0}.ci_id
WHERE {0}.attr_id={2:d}
GROUP BY {0}.ci_id
GROUP BY {0}.value
"""
QUERY_CI_BY_ATTR_NAME = """

View File

@ -139,6 +139,12 @@ class Search(object):
"ORDER BY B.ci_id {1} LIMIT {0:d}, {2};".format(
(self.page - 1) * self.count, sort_type, self.count))
elif self.type_id_list:
self.query_sql = """SELECT B.ci_id
FROM ({0}) AS B {1}""".format(
query_sql,
"INNER JOIN cis on cis.ci_id=B.ci_id "
"WHERE cis.type_id in ({0}) ".format(
",".join(self.type_id_list)))
return """SELECT SQL_CALC_FOUND_ROWS DISTINCT B.ci_id
FROM ({0}) AS B {1}""".format(
query_sql,
@ -148,6 +154,10 @@ class Search(object):
(self.page - 1) * self.count, sort_type, self.count,
",".join(self.type_id_list)))
else:
self.query_sql = """SELECT B.ci_id
FROM ({0}) AS B {1}""".format(
query_sql,
"INNER JOIN cis on cis.ci_id=B.ci_id ")
return """SELECT SQL_CALC_FOUND_ROWS DISTINCT B.ci_id
FROM ({0}) AS B {1}""".format(
query_sql,
@ -172,6 +182,12 @@ class Search(object):
(self.page - 1) * self.count,
sort_type, self.count)
elif self.type_id_list:
self.query_sql = """SELECT C.ci_id
FROM ({0}) AS C
INNER JOIN cis on cis.ci_id=C.ci_id
WHERE cis.type_id in ({1})""".format(
new_table,
",".join(self.type_id_list))
return """SELECT SQL_CALC_FOUND_ROWS DISTINCT C.ci_id
FROM ({0}) AS C
INNER JOIN cis on cis.ci_id=C.ci_id
@ -306,6 +322,7 @@ class Search(object):
table_name = TableMap(attr_name=k).table_name
query_sql = FACET_QUERY.format(
table_name, self.query_sql, attr.attr_id)
current_app.logger.debug(query_sql)
result = db.session.execute(query_sql).fetchall()
facet[k] = result
facet_result = dict()

View File

@ -30,6 +30,7 @@ class CITypeAttribute(db.Model):
db.ForeignKey("ci_attributes.attr_id"),
primary_key=True)
is_required = db.Column(db.Boolean, default=False)
order = db.Column(db.Integer, default=0)
__table_args__ = (db.UniqueConstraint("type_id", "attr_id",
name="type_attr_uniq"), )