Пример #1
0
    def _get_all_rel_tables(self, tb_id, result, tb_map, dep=0, index=0):
        """
        获取一张表的所有被依赖表
        :param tb_id:
        :param result:
        :param dep:
        :param tb_map: 用于判断是否存在循环依赖,防止死循环
        :param index: 被依赖表的索引,用于按照依赖关系排序,保证合表次序不会错乱
        :return:
        """
        if tb_id in tb_map:
            raise Exception("there is a cycle in the relation graph")

        tb_map[tb_id] = dep
        share_model = Share()
        shares = share_model.get({Share.TB_ID: tb_id}, (Share.SH_ID, ))
        sh_ids = [s[Share.SH_ID] for s in shares]
        del share_model
        tb_ids = [tb_id] + sh_ids
        rel_tables = self.get_rel_tables(tb_ids)
        for rel_tb in rel_tables:
            rel_tb['id'] = index
            index += 1
        dep += 1
        for rel_table in rel_tables:
            rel_tb_id = rel_table[Relation.TB_ID]
            result.append(rel_table)
            index = self._get_all_rel_tables(rel_tb_id, result, tb_map, dep,
                                             index)
        tb_map.pop(tb_id)
        return index
Пример #2
0
 def add_with_share(self, params):
     field_id = self.create(params)
     tb_or_share_id = params[self.TB_ID]
     share_model = Share()
     shares = share_model.get({Share.TB_ID: tb_or_share_id},
                              (Share.SH_ID, Share.COL_FILTER))
     for share in shares:
         col_filter = json.loads(share[Share.COL_FILTER])
         col_filter.append(field_id)
Пример #3
0
 def update(self, tb_id, params, update_share_version=True, is_del=False):
     if TB.VERSION in params and update_share_version:
         # 更新此表依赖的分享表的version
         share_model = Share()
         shares = share_model.get(
             {Share.TB_ID: tb_id},
             (Share.SH_ID, Share.VERSION, Share.ROW_FILTER, Share.DEP_ID))
         if shares:
             cond = (VField.FIELD_ID, VField.TITLE, VField.AGGREGATOR)
             table_vfield = VField().get(
                 {
                     VField.TB_ID: tb_id,
                     VField.FLAG: VField.TABLE_VFIELD_FLAG
                 }, cond)
             tb_info = self.get_one({TB.TB_ID: tb_id}, (TB.STORAGE_ID, ))
             storage_id = tb_info[TB.STORAGE_ID]
             # todo: 这里依赖mobius实现的不太好
             mobius = Mobius()
             for share in shares:
                 share[Share.VERSION] = 0 if share[
                     Share.VERSION] is None else share[Share.VERSION]
                 update_info = {Share.VERSION: share[Share.VERSION] + 1}
                 # 更新分享表的数据条数
                 if share[Share.
                          ROW_FILTER] == '[]' and not share[Share.DEP_ID]:
                     if TB.DATA_COUNT in params:
                         update_info[Share.DATA_COUNT] = params[
                             TB.DATA_COUNT]
                 else:
                     if TB.DATA_COUNT in params and params[
                             TB.DATA_COUNT] == 0:
                         update_info[Share.DATA_COUNT] = 0
                     else:
                         dep_list = [share]
                         self.find_parent_sh(shares, share[Share.SH_ID],
                                             dep_list)
                         row_filter = []
                         for sh in dep_list:
                             row_filter += json.loads(sh[Share.ROW_FILTER])
                         expand_filter = expand_vfield(
                             row_filter, table_vfield)
                         where = ' and '.join(expand_filter)
                         if not expand_filter and TB.DATA_COUNT in params:
                             update_info[Share.DATA_COUNT] = params[
                                 TB.DATA_COUNT]
                         else:
                             try:
                                 count_data = mobius.query(
                                     'select count(1) as count from %s where %s'
                                     % (storage_id, where))
                                 update_info[Share.DATA_COUNT] = count_data[
                                     'data'][0][0]
                             except Exception as e:
                                 self.logger.error(e)
                 share_model.update(share[Share.SH_ID], update_info)
     return self._update({TB.TB_ID: tb_id, 'is_del': is_del}, params)
Пример #4
0
    def get_cascade_update_plan(self, tb_id_list=[]):
        """
        此接口可以接收多个tb_id作为参数,根据级联更新关系给出一个执行级联更新的tb_id顺序
        :param tb_id_list:
        :return: 区别于get_all_rel_tables,此函数返回数列返回已经是排好序并去重后的结果
        """
        if not tb_id_list:
            return []

        return_list = []

        # 去除源tb_list对应的所有分配表
        share_model = Share()
        shares = share_model.get({Share.TB_ID: tb_id_list}, (Share.SH_ID, ))
        sh_ids = [s[Share.SH_ID] for s in shares]
        tb_id_list += sh_ids

        # 纪录第一层的所有tb_id, 这些tb_id是不用加入执行计划的,因为他们的类型不是view
        origin_tb_id_list = copy.deepcopy(tb_id_list)

        # 广度遍历并去重,如果有依赖重复出线的情况下,取更靠后的任务以保证任务依赖的正确
        while tb_id_list:
            # 第一层的tb是不用加入到结果的,因为不是gen类型的
            for tb_id in tb_id_list:
                if tb_id in return_list:
                    return_list.remove(tb_id)

                return_list.append(tb_id)

            share_tb_list = [
                share[Share.SH_ID] for share in share_model.get(
                    {Share.TB_ID: tb_id_list}, [Share.SH_ID])
            ]
            tb_ids = list(set(tb_id_list + share_tb_list))

            tb_id_list = list(
                set([
                    tmp_tb[Relation.TB_ID]
                    for tmp_tb in self.get_rel_tables(tb_ids)
                ]))

        return_list = [r for r in return_list if r not in origin_tb_id_list]
        return return_list
Пример #5
0
 def delete_with_share(self, tb_id, field_id):
     """
     删除字段,并从分配表中也将分配的字段移除
     """
     result = self._delete({Field.TB_ID: tb_id, Field.FIELD_ID: field_id})
     if result:
         share_model = Share()
         shares = share_model.get({Share.TB_ID: tb_id},
                                  (Share.SH_ID, Share.COL_FILTER))
         for share_info in shares:
             share_info[Share.COL_FILTER] = json.loads(
                 share_info[Share.COL_FILTER])
             if field_id in share_info[Share.COL_FILTER]:
                 share_info[Share.COL_FILTER].remove(field_id)
             share_model._update(
                 {Share.SH_ID: share_info[Share.SH_ID]},
                 {Share.COL_FILTER: share_info[Share.COL_FILTER]})
     return result
Пример #6
0
 def add_with_share(self, params):
     required_params = (Field.NAME, Field.TYPE)
     for rp in required_params:
         if rp not in params:
             self.logger.warn('缺失字段:%s' % rp)
             return None
     if not params.get(Field.FIELD_ID, ''):
         params[Field.FIELD_ID] = create_field_id()
     if params[Field.TYPE] == Field.NULL_DATA_TYPE:
         params[Field.TYPE] = Field.STRING_TYPE
     fid = params[Field.FIELD_ID]
     if self._create(params):
         tb_id = params[Field.TB_ID]
         share_model = Share()
         shares = share_model.get({Share.TB_ID: tb_id},
                                  (Share.SH_ID, Share.COL_FILTER))
         for share in shares:
             col_filter = json.loads(share[Share.COL_FILTER])
             col_filter.append(fid)
             share_model.update(share[Share.SH_ID],
                                {Share.COL_FILTER: col_filter})
         return fid
     else:
         return None