infi.clickhouse_orm/examples/db_explorer/server.py

88 lines
3.2 KiB
Python
Raw Normal View History

2020-07-08 08:14:40 +03:00
from infi.clickhouse_orm import Database, F
from charts import tables_piechart, columns_piechart, number_formatter, bytes_formatter
from flask import Flask
from flask import render_template
import sys
app = Flask(__name__)
@app.route('/')
def homepage_view():
2020-07-15 23:42:40 +03:00
'''
Root view that lists all databases.
'''
2020-07-08 08:14:40 +03:00
db = _get_db('system')
2020-07-15 23:42:40 +03:00
# Get all databases in the system.databases table
2020-07-08 08:14:40 +03:00
DatabasesTable = db.get_model_for_table('databases', system_table=True)
2020-07-15 23:42:40 +03:00
databases = DatabasesTable.objects_in(db).exclude(name='system')
databases = databases.order_by(F.lower(DatabasesTable.name))
# Generate the page
2020-07-08 08:14:40 +03:00
return render_template('homepage.html', db=db, databases=databases)
@app.route('/<db_name>/')
def database_view(db_name):
2020-07-15 23:42:40 +03:00
'''
A view that displays information about a single database.
'''
2020-07-08 08:14:40 +03:00
db = _get_db(db_name)
2020-07-15 23:42:40 +03:00
# Get all the tables in the database, by aggregating information from system.columns
2020-07-08 08:14:40 +03:00
ColumnsTable = db.get_model_for_table('columns', system_table=True)
2020-07-15 23:42:40 +03:00
tables = ColumnsTable.objects_in(db).filter(database=db_name).aggregate(
ColumnsTable.table,
2020-07-08 08:14:40 +03:00
compressed_size=F.sum(ColumnsTable.data_compressed_bytes),
uncompressed_size=F.sum(ColumnsTable.data_uncompressed_bytes),
ratio=F.sum(ColumnsTable.data_uncompressed_bytes) / F.sum(ColumnsTable.data_compressed_bytes)
2020-07-15 23:42:40 +03:00
)
tables = tables.order_by(F.lower(ColumnsTable.table))
# Generate the page
2020-07-08 08:14:40 +03:00
return render_template('database.html',
db=db,
tables=tables,
tables_piechart_by_rows=tables_piechart(db, 'total_rows', value_formatter=number_formatter),
tables_piechart_by_size=tables_piechart(db, 'total_bytes', value_formatter=bytes_formatter),
)
@app.route('/<db_name>/<tbl_name>/')
def table_view(db_name, tbl_name):
2020-07-15 23:42:40 +03:00
'''
A view that displays information about a single table.
'''
2020-07-08 08:14:40 +03:00
db = _get_db(db_name)
2020-07-15 23:42:40 +03:00
# Get table information from system.tables
2020-07-08 08:14:40 +03:00
TablesTable = db.get_model_for_table('tables', system_table=True)
tbl_info = TablesTable.objects_in(db).filter(database=db_name, name=tbl_name)[0]
2020-07-15 23:42:40 +03:00
# Get the SQL used for creating the table
2020-07-08 08:14:40 +03:00
create_table_sql = db.raw('SHOW CREATE TABLE %s FORMAT TabSeparatedRaw' % tbl_name)
2020-07-15 23:42:40 +03:00
# Get all columns in the table from system.columns
2020-07-08 08:14:40 +03:00
ColumnsTable = db.get_model_for_table('columns', system_table=True)
columns = ColumnsTable.objects_in(db).filter(database=db_name, table=tbl_name)
2020-07-15 23:42:40 +03:00
# Generate the page
2020-07-08 08:14:40 +03:00
return render_template('table.html',
db=db,
tbl_name=tbl_name,
tbl_info=tbl_info,
create_table_sql=create_table_sql,
columns=columns,
piechart=columns_piechart(db, tbl_name, 'data_compressed_bytes', value_formatter=bytes_formatter),
)
def _get_db(db_name):
2020-07-15 23:42:40 +03:00
'''
Returns a Database instance using connection information
from the command line arguments (optional).
'''
2020-07-08 08:14:40 +03:00
db_url = sys.argv[1] if len(sys.argv) > 1 else 'http://localhost:8123/'
username = sys.argv[2] if len(sys.argv) > 2 else None
password = sys.argv[3] if len(sys.argv) > 3 else None
return Database(db_name, db_url, username, password, readonly=True)
if __name__ == '__main__':
_get_db('system') # fail early on db connection problems
app.run(debug=True)