Index page only shows row counts for smaller databases

The index page now only shows row counts for immutable databases OR for
databases with less than 30 tables provided it could get a count for
each of those tables in less than 10ms.

Closes #467, Refs #460
This commit is contained in:
Simon Willison 2019-05-15 20:02:33 -07:00
commit 689cf9c139
3 changed files with 19 additions and 6 deletions

View file

@ -12,9 +12,9 @@
{% for database in databases %}
<h2 style="padding-left: 10px; border-left: 10px solid #{{ database.color }}"><a href="{{ database.path }}">{{ database.name }}</a></h2>
<p>
{{ "{:,}".format(database.table_rows_sum) }} rows in {{ database.tables_count }} table{% if database.tables_count != 1 %}s{% endif %}{% if database.tables_count and database.hidden_tables_count %}, {% endif -%}
{% if database.show_table_row_counts %}{{ "{:,}".format(database.table_rows_sum) }} rows in {% endif %}{{ database.tables_count }} table{% if database.tables_count != 1 %}s{% endif %}{% if database.tables_count and database.hidden_tables_count %}, {% endif -%}
{% if database.hidden_tables_count -%}
{{ "{:,}".format(database.hidden_table_rows_sum) }} rows in {{ database.hidden_tables_count }} hidden table{% if database.hidden_tables_count != 1 %}s{% endif -%}
{% if database.show_table_row_counts %}{{ "{:,}".format(database.hidden_table_rows_sum) }} rows in {% endif %}{{ database.hidden_tables_count }} hidden table{% if database.hidden_tables_count != 1 %}s{% endif -%}
{% endif -%}
{% if database.views_count -%}
{% if database.tables_count or database.hidden_tables_count %}, {% endif -%}

View file

@ -14,8 +14,12 @@ from datasette.version import __version__
from .base import HASH_LENGTH, RenderMixin
# Truncate table list on homepage at:
TRUNCATE_AT = 5
# Only attempt counts if less than this many tables:
COUNT_TABLE_LIMIT = 30
class IndexView(RenderMixin):
name = "index"
@ -26,11 +30,18 @@ class IndexView(RenderMixin):
async def get(self, request, as_format):
databases = []
for name, db in self.ds.databases.items():
table_counts = await db.table_counts(5)
views = await db.view_names()
tables = {}
table_names = await db.table_names()
hidden_table_names = set(await db.hidden_table_names())
for table in table_counts:
views = await db.view_names()
# Perform counts only for immutable or DBS with <= COUNT_TABLE_LIMIT tables
table_counts = {}
if not db.is_mutable or len(table_names) <= COUNT_TABLE_LIMIT:
table_counts = await db.table_counts(10)
# If any of these are None it means at least one timed out - ignore them all
if any(v is None for v in table_counts.values()):
table_counts = {}
tables = {}
for table in table_names:
table_columns = await self.ds.table_columns(name, table)
tables[table] = {
"name": table,
@ -38,7 +49,7 @@ class IndexView(RenderMixin):
"primary_keys": await self.ds.execute_against_connection_in_thread(
name, lambda conn: detect_primary_keys(conn, table)
),
"count": table_counts[table],
"count": table_counts.get(table),
"hidden": table in hidden_table_names,
"fts_table": await self.ds.execute_against_connection_in_thread(
name, lambda conn: detect_fts(conn, table)
@ -74,6 +85,7 @@ class IndexView(RenderMixin):
> TRUNCATE_AT,
"tables_count": len(visible_tables),
"table_rows_sum": sum((t["count"] or 0) for t in visible_tables),
"show_table_row_counts": bool(table_counts),
"hidden_table_rows_sum": sum(
t["count"] for t in hidden_tables if t["count"] is not None
),

View file

@ -445,6 +445,7 @@ def test_no_files_uses_memory_database(app_client_no_files):
"hidden_table_rows_sum": 0,
"hidden_tables_count": 0,
"name": ":memory:",
"show_table_row_counts": False,
"path": "/:memory:",
"table_rows_sum": 0,
"tables_count": 0,