From dc1d15247647c350ac73ad520229467180b8433c Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Wed, 21 Aug 2024 14:58:29 -0700 Subject: [PATCH] Stop counting at 10,000 rows when listing tables, refs #2398 --- datasette/database.py | 5 ++++- datasette/templates/database.html | 2 +- datasette/views/database.py | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/datasette/database.py b/datasette/database.py index c761dad7..da0ab1de 100644 --- a/datasette/database.py +++ b/datasette/database.py @@ -29,6 +29,9 @@ AttachedDatabase = namedtuple("AttachedDatabase", ("seq", "name", "file")) class Database: + # For table counts stop at this many rows: + count_limit = 10000 + def __init__( self, ds, @@ -376,7 +379,7 @@ class Database: try: table_count = ( await self.execute( - f"select count(*) from [{table}]", + f"select count(*) from (select * from [{table}] limit {self.count_limit + 1})", custom_time_limit=limit, ) ).rows[0][0] diff --git a/datasette/templates/database.html b/datasette/templates/database.html index f921bc2d..c6f3da99 100644 --- a/datasette/templates/database.html +++ b/datasette/templates/database.html @@ -60,7 +60,7 @@

{{ table.name }}{% if table.private %} 🔒{% endif %}{% if table.hidden %} (hidden){% endif %}

{% for column in table.columns %}{{ column }}{% if not loop.last %}, {% endif %}{% endfor %}

-

{% if table.count is none %}Many rows{% else %}{{ "{:,}".format(table.count) }} row{% if table.count == 1 %}{% else %}s{% endif %}{% endif %}

+

{% if table.count is none %}Many rows{% elif table.count == count_limit + 1 %}>{{ "{:,}".format(count_limit) }} rows{% else %}{{ "{:,}".format(table.count) }} row{% if table.count == 1 %}{% else %}s{% endif %}{% endif %}

{% endif %} {% endfor %} diff --git a/datasette/views/database.py b/datasette/views/database.py index 9ab061a1..61fe15e4 100644 --- a/datasette/views/database.py +++ b/datasette/views/database.py @@ -159,6 +159,7 @@ class DatabaseView(View): "show_hidden": request.args.get("_show_hidden"), "editable": True, "metadata": metadata, + "count_limit": db.count_limit, "allow_download": datasette.setting("allow_download") and not db.is_mutable and not db.is_memory, @@ -272,7 +273,7 @@ class QueryContext: async def get_tables(datasette, request, db): tables = [] database = db.name - table_counts = await db.table_counts(5) + table_counts = await db.table_counts(100) hidden_table_names = set(await db.hidden_table_names()) all_foreign_keys = await db.get_all_foreign_keys()