def progress_update(self, line): if not self.config.getboolean('main', 'timing'): return # Parse X-ClickHouse-Progress header now = datetime.now() progress = json.loads(line[23:].decode().strip()) progress = { 'timestamp': now, 'read_rows': int(progress['read_rows']), 'total_rows': int(progress['total_rows']), 'read_bytes': int(progress['read_bytes']), } # Calculate percentage completed and format initial message progress['percents'] = int( (progress['read_rows'] / progress['total_rows']) * 100) if progress['total_rows'] > 0 else 0 message = 'Progress: {} rows, {}'.format( numberunit_fmt(progress['read_rows']), sizeof_fmt(progress['read_bytes'])) # Calculate row and byte read velocity if self.progress: delta = (now - self.progress['timestamp']).total_seconds() if delta > 0: rps = (progress['read_rows'] - self.progress['read_rows']) / delta bps = (progress['read_bytes'] - self.progress['read_bytes']) / delta message += ' ({} rows/s, {}/s)'.format(numberunit_fmt(rps), sizeof_fmt(bps)) self.progress = progress self.progress_print(message, progress['percents'])
def handle_query(self, query, data=None, stream=False, verbose=False, query_id=None, compress=False, **kwargs): if query.rstrip(';') == '': return elif query.lower() in EXIT_COMMANDS: raise EOFError elif query.lower() in (r'\?', 'help'): rows = [ ['', ''], ["clickhouse-cli's custom commands:", ''], ['---------------------------------', ''], ['USE', "Change the current database."], ['SET', "Set an option for the current CLI session."], ['QUIT', "Exit clickhouse-cli."], ['HELP', "Show this help message."], ['', ''], ["PostgreSQL-like custom commands:", ''], ['--------------------------------', ''], [r'\l', "Show databases."], [r'\c', "Change the current database."], [r'\d, \dt', "Show tables in the current database."], [r'\d+', "Show table's schema."], [r'\ps', "Show current queries."], [r'\kill', "Kill query by its ID."], ['', ''], ["Query suffixes:", ''], ['---------------', ''], [r'\g, \G', "Use the Vertical format."], [r'\p', "Enable the pager."], ] for row in rows: self.echo.success('{:<8s}'.format(row[0]), nl=False) self.echo.info(row[1]) return elif query in (r'\d', r'\dt'): query = 'SHOW TABLES' elif query.startswith(r'\d+ '): query = 'DESCRIBE TABLE ' + query[4:] elif query == r'\l': query = 'SHOW DATABASES' elif query.startswith(r'\c '): query = 'USE ' + query[3:] elif query.startswith(r'\ps'): query = ( "SELECT query_id, user, address, elapsed, {}, memory_usage " "FROM system.processes WHERE query_id != '{}'").format( 'read_rows' if self.server_version[2] >= 54115 else 'rows_read', query_id) elif query.startswith(r'\kill '): self.client.kill_query(query[6:]) return response = '' self.progress_reset() try: response = self.client.query( query, fmt=self.format, data=data, stream=stream, verbose=verbose, query_id=query_id, compress=compress, ) except TimeoutError: self.echo.error("Error: Connection timeout.") return except ConnectionError: self.echo.error("Error: Failed to connect.") return except DBException as e: self.progress_reset() self.echo.error("\nQuery:") self.echo.error(query) self.echo.error("\n\nReceived exception from server:") self.echo.error(e.error) if self.stacktrace and e.stacktrace: self.echo.print("\nStack trace:") self.echo.print(e.stacktrace) self.echo.print('\nElapsed: {elapsed:.3f} sec.\n'.format( elapsed=e.response.elapsed.total_seconds())) return total_rows, total_bytes = self.progress_reset() self.echo.print() if stream: data = response.iter_lines() if hasattr( response, 'iter_lines') else response.data for line in data: print(line.decode('utf-8', 'ignore')) else: if response.data != '': print_func = print if self.config.getboolean('main', 'pager') or kwargs.pop( 'force_pager', False): print_func = self.echo.pager should_highlight_output = (verbose and self.highlight and self.highlight_output and response.format in PRETTY_FORMATS) formatter = TerminalFormatter() if self.highlight and self.highlight_truecolor: formatter = TerminalTrueColorFormatter( style=CHPygmentsStyle) if should_highlight_output: print_func( pygments.highlight(response.data, CHPrettyFormatLexer(), formatter)) else: print_func(response.data) if response.message != '': self.echo.print(response.message) self.echo.print() self.echo.success('Ok. ', nl=False) if response.rows is not None: self.echo.print('{rows_count} row{rows_plural} in set.'.format( rows_count=response.rows, rows_plural='s' if response.rows != 1 else '', ), end=' ') if self.config.getboolean( 'main', 'timing') and response.time_elapsed is not None: self.echo.print( 'Elapsed: {elapsed:.3f} sec. Processed: {rows} rows, {bytes} ({avg_rps} rows/s, {avg_bps}/s)' .format( elapsed=response.time_elapsed, rows=numberunit_fmt(total_rows), bytes=sizeof_fmt(total_bytes), avg_rps=numberunit_fmt(total_rows / max(response.time_elapsed, 0.001)), avg_bps=sizeof_fmt(total_bytes / max(response.time_elapsed, 0.001)), ), end='') self.echo.print('\n')