def get(self): args = self.parse_args([{ 'name': 'dashboard', 'required': True, 'location': 'args' }, { 'name': 'chart', 'required': True, 'location': 'args' }]) dbmeta = DBMeta(self.user_id) dashboard = dbmeta.dashboard('id', name=args['dashboard']).single() chart = dbmeta.chart(dashboard_id=dashboard.id, name=args['chart']).single() ds = dbmeta.datasource(id=chart.ds_id).single() connector = Connector(user_id=self.user_id, type=ds.type, db=ds.name, **ds.params) query = Query.load(chart.query, connector) result = query.execute() fields = [_['name'] for _ in chart.y_fields if _] data = chart_data(result, chart.x_fields, fields) self.response(ds_id=ds.id, table=chart.table, type=chart.type, sql=query.sql, xFields=chart.x_fields, yFields=chart.y_fields, **data)
def vtables(self): from model import DBMeta user_id = self.kwargs.get('user_id') ds_name = self.kwargs.get('db') if not user_id or not ds_name: return {} dbmeta = DBMeta(user_id) datasource = dbmeta.datasource(name=ds_name).single() vtables = dbmeta.vtable(ds_id=datasource.id).all() return [(tb.name, tb.query) for tb in vtables]
def post(self): args = self.parse_args([ { 'name': 'name', 'required': True, 'location': 'body' }, { 'name': 'ds_id', 'required': True, 'location': 'body' }, { 'name': 'rules', 'required': True, 'location': 'body' }, { 'name': 'type', 'required': True, 'location': 'body', 'default': 'join' }, ]) self.meta = DBMeta(self.user_id) if args['type'] == 'join': table_json = self.join_table() else: table_json = self.aggr_table() if not table_json: return if self.meta.vtable(name=args['name']).first(): self.response(409, u'已存在名字为 %s 的合表' % args['name']) return ds = self.meta.datasource(id=args['ds_id']).single() connector = Connector(user_id=self.user_id, type=ds.type, db=ds.name, **ds.params) engine = Engine(connector) if args['name'] in engine.tables(): self.response(409, u'原始库中已存在表(%s)' % args['name']) return vtb = self.meta.vtable(ds_id=args['ds_id'], name=args['name'], query=table_json) vtb.insert() self.meta.commit() self.response(message='success') del self.meta
def delete(self): args = self.parse_args([{ 'name': 'name', 'required': True, 'location': 'args' }]) db = DBMeta(self.user_id) ds = db.dashboard(name=args['name']) ds.delete() db.commit() self.response(message='success')
def post(self): args = self.parse_args([{ 'name': 'name', 'required': True, 'location': 'body' }]) db = DBMeta(self.user_id) ds = db.dashboard(name=args['name']) if ds.first(): self.response(409, u'已存在名字为 %s 的仪表盘' % args['name']) return ds.insert() db.commit() self.response(message='success')
def post(self): args = self.parse_args([{ 'name': 'names', 'required': True, 'location': 'body' }]) dbmeta = DBMeta(self.user_id) for name in args['names']: dsbd = dbmeta.dashboard(name=name) dashboard = dsbd.first() if dashboard: continue dsbd.insert() dbmeta.commit() self.response(message='success')
def get(self): args = self.parse_args([{ 'name': 'ds_id', 'required': True, 'location': 'args' }, { 'name': 'table', 'required': True, 'location': 'args' }, { 'name': 'filters', 'required': False, 'location': 'args', 'cast': json.loads, 'defalt': '[]' }, { 'name': 'xFields', 'required': False, 'location': 'args', 'cast': json.loads, 'defalt': '[]' }, { 'name': 'yFields', 'required': False, 'location': 'args', 'cast': json.loads, 'defalt': '[]' }]) self.dbmeta = DBMeta(self.user_id) ds = self.dbmeta.datasource(id=args['ds_id']).single() connector = Connector(user_id=self.user_id, type=ds.type, db=ds.name, **ds.params) query = self.query self.logger.info('%s' % query.json()) query.deepbind(connector) result = query.execute() self.response(sql=query.sql, data=result.json_data, schema=result.schema, columns=result.columns) del self.dbmeta
def get(self): args = self.parse_args([{ 'name': 'dashboard', 'required': True, 'location': 'args' }]) dbmeta = DBMeta(self.user_id) dashboard = dbmeta.dashboard(name=args['dashboard']).first() if not dashboard: self.response(404, message='不存在的仪表盘') return charts = dbmeta.chart('name', dashboard_id=dashboard.id).all() self.response(**{ 'total': len(charts), 'charts': [c.name for c in charts] })
def post(self): args = self.parse_args([{ 'name': 'username', 'required': True, 'location': 'body' }, { 'name': 'password', 'required': True, 'location': 'body' }]) try: db = DBMeta() user = db.user(**args).auth() except Exception, e: self.logger.warn(e, exc_info=True) self.response(401, 'Auth failed!') return
def get(self): args = self.parse_args([{ 'name': 'pageno', 'required': False, 'location': 'args' }, { 'name': 'pagesize', 'required': False, 'location': 'args' }, { 'name': 'name', 'required': False, 'location': 'args' }]) dbmeta = DBMeta(self.user_id) kwargs = {} if args.get('name'): kwargs['name'] = args['name'] datasources = dbmeta.datasource(**kwargs).all() result = [] for ds in datasources: item = { 'id': ds.id, 'name': ds.name, 'ctime': ds.ctime, 'utime': ds.utime, 'type': ds.type.upper() } connector = Connector(type=ds.type.upper(), user_id=self.user_id, db=ds.name, **ds.params) if isinstance(connector, ODOConnector): engine = Engine(connector) ds.params['filelist'] = engine.tables() item.update(ds.params) result.append(item) self.response(**{"total": len(result), "datasources": result})
def delete(self): args = self.parse_args([ { 'name': 'ids', 'required': True, 'location': 'args', 'cast': json.loads }, ]) db = DBMeta(self.user_id) for ds_id in args['ids']: ds = db.datasource(id=ds_id) datasource = ds.single() if datasource.type in FILEMETA: pass ds.delete() db.commit() self.response(message='success')
def delete(self): args = self.parse_args([ {'name': 'dashboard', 'required': True, 'location': 'args'}, {'name': 'chart', 'required': True, 'location': 'args'} ]) dbmeta = DBMeta(self.user_id) dsbd = dbmeta.dashboard('id', name=args['dashboard']).single() dbmeta.chart(name=args['chart'], dashboard_id=dsbd.id).delete() dbmeta.commit() self.response(message='success')
def post(self): args = self.parse_args([ {'name': 'name', 'required': True, 'location': 'body'}, {'name': 'type', 'required': True, 'location': 'body'}, {'name': 'params', 'required': True, 'location': 'body'} ]) args['params'] = params(args['type'], **args['params']) db = DBMeta(self.user_id) dss = db.datasource(name=args['name']).all() if dss: self.response(409, message='已存在名称为 %s 的数据源' % args['name']) return if not args['params'].get('filelist'): connector = Connector(args['type'], db=args['name'], **args['params']) databases = Engine(connector).databases() if args['name'] not in databases: self.response(412, u'数据库中不存在 %s 库' % args['name']) return ds = db.datasource(**args) ds.insert() db.commit() self.response(message='success')
def get(self): args = self.parse_args([{ 'name': 'ds_id', 'required': True, 'location': 'args', 'cast': int }, { 'name': 'tables', 'required': False, 'location': 'args', 'cast': json.loads }]) tables = args.get('tables') db = DBMeta(self.user_id) ds = db.datasource(id=args['ds_id']).single() connector = Connector(user_id=self.user_id, type=ds.type, db=ds.name, **ds.params) engine = Engine(connector) dbmeta = DBMeta(self.user_id) vtables = dbmeta.vtable(ds_id=args['ds_id']).all() all_table = engine.tables() + [_.name for _ in vtables] result = [{ 'name': _, 'schema': [_['name'] for _ in engine.schema(_)] } for _ in all_table if not tables or _ in tables] self.response(**{'total': len(result), 'schema': result})
def get(self): args = self.parse_args([ {'name': 'ds_id', 'required': True, 'location': 'args', 'cast': int}, {'name': 'table', 'required': True, 'location': 'args'}, {'name': 'xFields', 'required': True, 'location': 'args', 'cast': json.loads}, {'name': 'yFields', 'required': True, 'location': 'args', 'cast': json.loads}, {'name': 'filters', 'required': False, 'location': 'args', 'cast': json.loads, 'defalt': '[]'}, {'name': 'type', 'required': True, 'location': 'args'} ]) self.dbmeta = DBMeta(self.user_id) ds = self.dbmeta.datasource(id=args['ds_id']).single() connector = Connector(user_id=self.user_id, type=ds.type, db=ds.name, **ds.params) query = self.query self.logger.info('%s' % query.json()) query.deepbind(connector) result = query.execute() fields = [_['name'][0] for _ in self.args['yFields'] if _['name']] self.response(sql=query.sql, **chart_data(result, args['xFields'], fields)) del self.dbmeta
def put(self): args = self.parse_args([ {'name': 'name', 'required': True, 'location': 'body'}, {'name': 'dashboard', 'required': True, 'location': 'body'}, {'name': 'ds_id', 'required': True, 'location': 'body', 'cast': int}, {'name': 'table', 'required': True, 'location': 'body'}, {'name': 'xFields', 'required': True, 'location': 'body'}, {'name': 'yFields', 'required': True, 'location': 'body'}, {'name': 'type', 'required': True, 'location': 'body'} ]) self.dbmeta = DBMeta(self.user_id) query = self.query.json() dashboard = self.dbmeta.dashboard('id', name=args['dashboard']).single() y_fields = [{'name': _['name'][0], 'aggr_func': _['name'][1]} for _ in self.args['yFields'] if _['name']] chart = self.dbmeta.chart(name=args['name'], dashboard_id=dashboard.id) chart.update( ds_id=args['ds_id'], table=args['table'], query=query, x_fields=args['xFields'], y_fields=y_fields, type=args['type'] ) self.dbmeta.commit() self.response(message='success')
def delete(self): args = self.parse_args([ {'name': 'id', 'required': True, 'location': 'args'} ]) db = DBMeta(self.user_id) db.datasource(id=args['id']).delete() db.commit() self.response(message='success')
def post(self): args = self.parse_args([ {'name': 'name', 'required': True, 'location': 'body'}, {'name': 'dashboards', 'required': True, 'location': 'body'}, {'name': 'ds_id', 'required': True, 'location': 'body', 'cast': int}, {'name': 'table', 'required': True, 'location': 'body'}, {'name': 'xFields', 'required': True, 'location': 'body'}, {'name': 'yFields', 'required': True, 'location': 'body'}, {'name': 'type', 'required': True, 'location': 'body'} ]) self.dbmeta = DBMeta(self.user_id) query = self.query.json() y_fields = [{'name': _['name'][0], 'aggr_func': _['name'][1]} for _ in self.args['yFields'] if _['name']] dsbd = self.dbmeta.dashboard('id', 'name') dsbds = dsbd.filter(dsbd.column('name').in_(args['dashboards'])).all() dsbds = {_.id: _.name for _ in dsbds} for dsid, dsbdname in dsbds.items(): ret = self.dbmeta.chart('dashboard_id', name=args['name'], dashboard_id_id=dsid).all() if ret: self.response(412, message=u'仪表盘 %s 中已存在名字为 %s 的图表' % (dsbdname, args['name'])) return chart = self.dbmeta.chart(name=args['name'], ds_id=args['ds_id'], table=args['table'], query=query, x_fields=args['xFields'], y_fields=y_fields, type=args['type']) for dashboard in args['dashboards']: dashboard = self.dbmeta.dashboard(name=dashboard).first() if not dashboard: continue chart.dashboard_id = dashboard.id chart.insert() self.dbmeta.commit() self.response(message='success') del self.dbmeta
def post(self): args = self.parse_args([{ 'name': 'username', 'required': True, 'location': 'body' }, { 'name': 'password', 'required': True, 'location': 'body' }]) reg = re.match(r'^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$', args['username']) if not reg: self.response(400, '邮箱格式有误') return try: db = DBMeta() db.user(**args).insert() except Exception, e: self.logger.warn(e, exc_info=True) self.response(409, '用户已存在') return
def put(self): args = self.parse_args([ {'name': 'id', 'required': True, 'location': 'body'}, {'name': 'name', 'required': True, 'location': 'body'}, {'name': 'type', 'required': True, 'location': 'body'}, {'name': 'params', 'required': True, 'location': 'body'} ]) args['params'] = params(args['type'], **args['params']) db = DBMeta(self.user_id) db.datasource(id=args['id']).update(**args) db.commit() self.response(message='success')
def get(self): dbmeta = DBMeta(self.user_id) dashboards = dbmeta.dashboard('id', 'name').all() result = [{'id': db.id, 'name': db.name} for db in dashboards] self.response(**{'total': len(result), 'dashboards': result})
def auth(self): from model import DBMeta if self.request.path == '/api/login': return try: user = self.get_cookie('user') except Exception, e: self.logger.error(e, exc_info=True) raise UnAuthentication() if not user: raise UnAuthentication() if time.time() - user.get('access', 0) > 60 * 60 * 24: raise AuthExpire() try: db = DBMeta() db = db.user(**user).auth() self.user_id = db['id'] except Exception: raise UnAuthentication() def data_received(self, chunk): pass class UnAuthentication(HTTPError): def __init__(self): super(UnAuthentication, self).__init__(401, 'Auth failed!') class AuthExpire(HTTPError):
class AggrPreviewHandler(BaseHandler): def get(self): args = self.parse_args([{ 'name': 'ds_id', 'required': True, 'location': 'args' }, { 'name': 'table', 'required': True, 'location': 'args' }, { 'name': 'filters', 'required': False, 'location': 'args', 'cast': json.loads, 'defalt': '[]' }, { 'name': 'xFields', 'required': False, 'location': 'args', 'cast': json.loads, 'defalt': '[]' }, { 'name': 'yFields', 'required': False, 'location': 'args', 'cast': json.loads, 'defalt': '[]' }]) self.dbmeta = DBMeta(self.user_id) ds = self.dbmeta.datasource(id=args['ds_id']).single() connector = Connector(user_id=self.user_id, type=ds.type, db=ds.name, **ds.params) query = self.query self.logger.info('%s' % query.json()) query.deepbind(connector) result = query.execute() self.response(sql=query.sql, data=result.json_data, schema=result.schema, columns=result.columns) del self.dbmeta @property def where(self): wheres = [] for condition in self.args.get('filters', []): if not condition['name'] or not condition['operator']: continue name = condition['name'] operator = condition['operator'] if condition.get('value_type', 'value') == 'value': value = condition['value'] else: value = Text(condition['value']) c = Condition(Column(name), operator, value) wheres.append(c.json()) return wheres @property def table(self): chart = self.dbmeta.vtable(name=self.args['table'], ds_id=self.args['ds_id']).first() if chart: return chart.query return Table(self.args['table']).json() @property def columns(self): fields = [_['name'] for _ in self.args['yFields'] if _['name']] result = [function(func_name, name) for name, func_name in fields] group_by = self.group_by if group_by: return group_by + result if not result: return [] return result @property def group_by(self): if not self.args['xFields']: return None return [Column(_).json() for _ in self.args['xFields']] @property def query(self): table = self.table if table['type'] == 'table': return Query(table=self.table, columns=self.columns, where=self.where, group_by=self.group_by, limit=10) else: query = Query.load(self.table) name = self.args['table'] query.alias(name) return Query(table=name, columns=self.columns, where=self.where, group_by=self.group_by, limit=10).bind(query)
def get(self): args = self.parse_args([{ 'name': 'ds_id', 'required': True, 'location': 'args' }, { 'name': 'tables', 'required': True, 'location': 'args', 'cast': json.loads }, { 'name': 'rules', 'required': False, 'location': 'args', 'cast': json.loads }]) result = [] rules = args['rules'] tables = args['tables'] dbmeta = DBMeta(self.user_id) ds = dbmeta.datasource(id=args['ds_id']).single() connector = Connector(user_id=self.user_id, type=ds.type, db=ds.name, **ds.params) engine = Engine(connector) wheres = parse_where(rules) vtables = dbmeta.vtable(ds_id=self.args['ds_id']).all() vtables = [(tb.name, tb.query) for tb in vtables] for tablenames, clause in wheres.items(): columns = [] for name in tablenames: columns += [ Column(name, _['name']).label('%s.%s' % (name, _['name'])) for _ in engine.schema(name) ] table_json = Table(*columns).select_from(*tablenames).where( *clause).json() q = Query(table=table_json, limit=10) q.bind(connector) ret = q.execute() result.append({ 'data': ret.json_data, 'sql': q.sql, 'columns': ret.columns, 'names': tablenames }) keys = sum(wheres.keys(), ()) tables = [(_, dict(vtables).get(_, _)) for _ in tables if _ not in keys] for name, tb in tables: q = get_query(tb, 10) q.bind(connector) ret = q.execute() result.append({ 'data': ret.json_data, 'columns': ret.columns, 'names': [name], 'schema': ret.schema }) self.response(total=len(result), tables=result)
class TableHandler(BaseHandler): def post(self): args = self.parse_args([ { 'name': 'name', 'required': True, 'location': 'body' }, { 'name': 'ds_id', 'required': True, 'location': 'body' }, { 'name': 'rules', 'required': True, 'location': 'body' }, { 'name': 'type', 'required': True, 'location': 'body', 'default': 'join' }, ]) self.meta = DBMeta(self.user_id) if args['type'] == 'join': table_json = self.join_table() else: table_json = self.aggr_table() if not table_json: return if self.meta.vtable(name=args['name']).first(): self.response(409, u'已存在名字为 %s 的合表' % args['name']) return ds = self.meta.datasource(id=args['ds_id']).single() connector = Connector(user_id=self.user_id, type=ds.type, db=ds.name, **ds.params) engine = Engine(connector) if args['name'] in engine.tables(): self.response(409, u'原始库中已存在表(%s)' % args['name']) return vtb = self.meta.vtable(ds_id=args['ds_id'], name=args['name'], query=table_json) vtb.insert() self.meta.commit() self.response(message='success') del self.meta def join_table(self): wheres = parse_where(self.args['rules']) ds = self.meta.datasource(id=self.args['ds_id']).single() engine = Engine( Connector(user_id=self.user_id, type=ds.type, db=ds.name, **ds.params)) if len(wheres) != 1: self.response(422, '需要最终合成一张表') return tablenames, clause = wheres.items()[0] columns = [] vtables = self.meta.vtable(ds_id=self.args['ds_id']).all() vtables = {tb.name: tb.query for tb in vtables} for name in tablenames: columns += [ Column(name, _['name']).label('%s.%s' % (name, _['name'])) for _ in self.schema(engine, vtables, name) ] return Table(*columns).select_from(*tablenames).where(*clause).json() def aggr_table(self): rule = self.args['rules'] table = rule['table'] return Query(table=table, columns=self.columns, where=self.where, group_by=self.group_by, order_by=None, limit=None).json() def schema(self, engine, vtables, name): if name in engine.tables(): return engine.schema(name) return [{ 'name': (_.alias or _.value) } for _ in get_query(vtables[name]).columns] @property def where(self): wheres = [] filters = self.args['rules'].get('filters', []) for condition in filters: if not condition['name'] or not condition['operator']: continue name = condition['name'] operator = condition['operator'] value = condition['value'] c = Condition(Column(name), operator, value) wheres.append(c.json()) return wheres @property def columns(self): y_fields = self.args['rules']['y_fields'] fields = [_['name'] for _ in y_fields if _['name']] result = [function(func_name, name) for name, func_name in fields] group_by = self.group_by if group_by: return group_by + result if not result: return [] return result @property def group_by(self): x_fields = self.args['rules']['x_fields'] if not x_fields: return None return [Column(_).json() for _ in x_fields]
class ChartHandler(BaseHandler): def get(self): args = self.parse_args([ {'name': 'ds_id', 'required': True, 'location': 'args', 'cast': int}, {'name': 'table', 'required': True, 'location': 'args'}, {'name': 'xFields', 'required': True, 'location': 'args', 'cast': json.loads}, {'name': 'yFields', 'required': True, 'location': 'args', 'cast': json.loads}, {'name': 'filters', 'required': False, 'location': 'args', 'cast': json.loads, 'defalt': '[]'}, {'name': 'type', 'required': True, 'location': 'args'} ]) self.dbmeta = DBMeta(self.user_id) ds = self.dbmeta.datasource(id=args['ds_id']).single() connector = Connector(user_id=self.user_id, type=ds.type, db=ds.name, **ds.params) query = self.query self.logger.info('%s' % query.json()) query.deepbind(connector) result = query.execute() fields = [_['name'][0] for _ in self.args['yFields'] if _['name']] self.response(sql=query.sql, **chart_data(result, args['xFields'], fields)) del self.dbmeta def post(self): args = self.parse_args([ {'name': 'name', 'required': True, 'location': 'body'}, {'name': 'dashboards', 'required': True, 'location': 'body'}, {'name': 'ds_id', 'required': True, 'location': 'body', 'cast': int}, {'name': 'table', 'required': True, 'location': 'body'}, {'name': 'xFields', 'required': True, 'location': 'body'}, {'name': 'yFields', 'required': True, 'location': 'body'}, {'name': 'type', 'required': True, 'location': 'body'} ]) self.dbmeta = DBMeta(self.user_id) query = self.query.json() y_fields = [{'name': _['name'][0], 'aggr_func': _['name'][1]} for _ in self.args['yFields'] if _['name']] dsbd = self.dbmeta.dashboard('id', 'name') dsbds = dsbd.filter(dsbd.column('name').in_(args['dashboards'])).all() dsbds = {_.id: _.name for _ in dsbds} for dsid, dsbdname in dsbds.items(): ret = self.dbmeta.chart('dashboard_id', name=args['name'], dashboard_id_id=dsid).all() if ret: self.response(412, message=u'仪表盘 %s 中已存在名字为 %s 的图表' % (dsbdname, args['name'])) return chart = self.dbmeta.chart(name=args['name'], ds_id=args['ds_id'], table=args['table'], query=query, x_fields=args['xFields'], y_fields=y_fields, type=args['type']) for dashboard in args['dashboards']: dashboard = self.dbmeta.dashboard(name=dashboard).first() if not dashboard: continue chart.dashboard_id = dashboard.id chart.insert() self.dbmeta.commit() self.response(message='success') del self.dbmeta def delete(self): args = self.parse_args([ {'name': 'dashboard', 'required': True, 'location': 'args'}, {'name': 'chart', 'required': True, 'location': 'args'} ]) dbmeta = DBMeta(self.user_id) dsbd = dbmeta.dashboard('id', name=args['dashboard']).single() dbmeta.chart(name=args['chart'], dashboard_id=dsbd.id).delete() dbmeta.commit() self.response(message='success') def put(self): args = self.parse_args([ {'name': 'name', 'required': True, 'location': 'body'}, {'name': 'dashboard', 'required': True, 'location': 'body'}, {'name': 'ds_id', 'required': True, 'location': 'body', 'cast': int}, {'name': 'table', 'required': True, 'location': 'body'}, {'name': 'xFields', 'required': True, 'location': 'body'}, {'name': 'yFields', 'required': True, 'location': 'body'}, {'name': 'type', 'required': True, 'location': 'body'} ]) self.dbmeta = DBMeta(self.user_id) query = self.query.json() dashboard = self.dbmeta.dashboard('id', name=args['dashboard']).single() y_fields = [{'name': _['name'][0], 'aggr_func': _['name'][1]} for _ in self.args['yFields'] if _['name']] chart = self.dbmeta.chart(name=args['name'], dashboard_id=dashboard.id) chart.update( ds_id=args['ds_id'], table=args['table'], query=query, x_fields=args['xFields'], y_fields=y_fields, type=args['type'] ) self.dbmeta.commit() self.response(message='success') @property def where(self): wheres = [] for condition in self.args.get('filters', []): if not condition['name'] or not condition['operator']: continue name = condition['name'] operator = condition['operator'] if condition.get('value_type', 'value') == 'value': value = condition['value'] else: value = Text(condition['value']) c = Condition(Column(name), operator, value) wheres.append(c.json()) return wheres @property def table(self): chart = self.dbmeta.vtable(name=self.args['table'], ds_id=self.args['ds_id']).first() if chart: return chart.query return Table(self.args['table']).json() @property def columns(self): fields = [_['name'] for _ in self.args['yFields'] if _['name']] result = [function(func_name, name) for name, func_name in fields] group_by = self.group_by if group_by: return group_by+result return result @property def group_by(self): if not self.args['xFields']: return None return [Column(_).json() for _ in self.args['xFields']] @property def query(self): table = self.table if table['type'] == 'table': return Query(table=self.table, columns=self.columns, where=self.where, group_by=self.group_by, limit=500) else: query = Query.load(self.table) name = self.args['table'] query.alias(name) return Query(table=name, columns=self.columns, where=self.where, group_by=self.group_by, limit=500).bind(query)