mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
?_facet_size=100 parameter, closes #1332
This commit is contained in:
parent
5e9672c9bb
commit
9789b94da4
5 changed files with 73 additions and 4 deletions
|
|
@ -101,6 +101,14 @@ class Facet:
|
||||||
# [('_foo', 'bar'), ('_foo', '2'), ('empty', '')]
|
# [('_foo', 'bar'), ('_foo', '2'), ('empty', '')]
|
||||||
return urllib.parse.parse_qsl(self.request.query_string, keep_blank_values=True)
|
return urllib.parse.parse_qsl(self.request.query_string, keep_blank_values=True)
|
||||||
|
|
||||||
|
def get_facet_size(self):
|
||||||
|
facet_size = self.ds.setting("default_facet_size")
|
||||||
|
max_returned_rows = self.ds.setting("max_returned_rows")
|
||||||
|
custom_facet_size = self.request.args.get("_facet_size")
|
||||||
|
if custom_facet_size and custom_facet_size.isdigit():
|
||||||
|
facet_size = int(custom_facet_size)
|
||||||
|
return min(facet_size, max_returned_rows)
|
||||||
|
|
||||||
async def suggest(self):
|
async def suggest(self):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
@ -136,7 +144,7 @@ class ColumnFacet(Facet):
|
||||||
async def suggest(self):
|
async def suggest(self):
|
||||||
row_count = await self.get_row_count()
|
row_count = await self.get_row_count()
|
||||||
columns = await self.get_columns(self.sql, self.params)
|
columns = await self.get_columns(self.sql, self.params)
|
||||||
facet_size = self.ds.setting("default_facet_size")
|
facet_size = self.get_facet_size()
|
||||||
suggested_facets = []
|
suggested_facets = []
|
||||||
already_enabled = [c["config"]["simple"] for c in self.get_configs()]
|
already_enabled = [c["config"]["simple"] for c in self.get_configs()]
|
||||||
for column in columns:
|
for column in columns:
|
||||||
|
|
@ -186,7 +194,7 @@ class ColumnFacet(Facet):
|
||||||
|
|
||||||
qs_pairs = self.get_querystring_pairs()
|
qs_pairs = self.get_querystring_pairs()
|
||||||
|
|
||||||
facet_size = self.ds.setting("default_facet_size")
|
facet_size = self.get_facet_size()
|
||||||
for source_and_config in self.get_configs():
|
for source_and_config in self.get_configs():
|
||||||
config = source_and_config["config"]
|
config = source_and_config["config"]
|
||||||
source = source_and_config["source"]
|
source = source_and_config["source"]
|
||||||
|
|
@ -338,7 +346,7 @@ class ArrayFacet(Facet):
|
||||||
facet_results = {}
|
facet_results = {}
|
||||||
facets_timed_out = []
|
facets_timed_out = []
|
||||||
|
|
||||||
facet_size = self.ds.setting("default_facet_size")
|
facet_size = self.get_facet_size()
|
||||||
for source_and_config in self.get_configs():
|
for source_and_config in self.get_configs():
|
||||||
config = source_and_config["config"]
|
config = source_and_config["config"]
|
||||||
source = source_and_config["source"]
|
source = source_and_config["source"]
|
||||||
|
|
@ -449,7 +457,7 @@ class DateFacet(Facet):
|
||||||
facet_results = {}
|
facet_results = {}
|
||||||
facets_timed_out = []
|
facets_timed_out = []
|
||||||
args = dict(self.get_querystring_pairs())
|
args = dict(self.get_querystring_pairs())
|
||||||
facet_size = self.ds.setting("default_facet_size")
|
facet_size = self.get_facet_size()
|
||||||
for source_and_config in self.get_configs():
|
for source_and_config in self.get_configs():
|
||||||
config = source_and_config["config"]
|
config = source_and_config["config"]
|
||||||
source = source_and_config["source"]
|
source = source_and_config["source"]
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,8 @@ This works for both the HTML interface and the ``.json`` view. When enabled, fac
|
||||||
|
|
||||||
If Datasette detects that a column is a foreign key, the ``"label"`` property will be automatically derived from the detected label column on the referenced table.
|
If Datasette detects that a column is a foreign key, the ``"label"`` property will be automatically derived from the detected label column on the referenced table.
|
||||||
|
|
||||||
|
The default number of facet results returned is 30, controlled by the :ref:`setting_default_facet_size` setting. You can increase this on an individual page by adding ``?_facet_size=100`` to the query string, up to a maximum of :ref:`setting_max_returned_rows` (which defaults to 1000).
|
||||||
|
|
||||||
Facets in metadata.json
|
Facets in metadata.json
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -371,6 +371,12 @@ Special table arguments
|
||||||
Pagination by continuation token - pass the token that was returned in the
|
Pagination by continuation token - pass the token that was returned in the
|
||||||
``"next"`` property by the previous page.
|
``"next"`` property by the previous page.
|
||||||
|
|
||||||
|
``?_facet=column``
|
||||||
|
Facet by column. Can be applied multiple times, see :ref:`facets`. Only works on the default JSON output, not on any of the custom shapes.
|
||||||
|
|
||||||
|
``?_facet_size=100``
|
||||||
|
Increase the number of facet results returned for each facet.
|
||||||
|
|
||||||
``?_trace=1``
|
``?_trace=1``
|
||||||
Turns on tracing for this page: SQL queries executed during the request will
|
Turns on tracing for this page: SQL queries executed during the request will
|
||||||
be gathered and included in the response, either in a new ``"_traces"`` key
|
be gathered and included in the response, either in a new ``"_traces"`` key
|
||||||
|
|
|
||||||
|
|
@ -619,6 +619,7 @@ Each Facet subclass implements a new type of facet operation. The class should l
|
||||||
# using self.sql and self.params as the starting point
|
# using self.sql and self.params as the starting point
|
||||||
facet_results = {}
|
facet_results = {}
|
||||||
facets_timed_out = []
|
facets_timed_out = []
|
||||||
|
facet_size = self.get_facet_size()
|
||||||
# Do some calculations here...
|
# Do some calculations here...
|
||||||
for column in columns_selected_for_facet:
|
for column in columns_selected_for_facet:
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -347,3 +347,55 @@ async def test_json_array_with_blanks_and_nulls():
|
||||||
"toggle_url": "http://localhost/test_json_array/foo.json?_facet_array=json_column",
|
"toggle_url": "http://localhost/test_json_array/foo.json?_facet_array=json_column",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_facet_size():
|
||||||
|
ds = Datasette([], memory=True, config={"max_returned_rows": 50})
|
||||||
|
db = ds.add_database(Database(ds, memory_name="test_facet_size"))
|
||||||
|
await db.execute_write(
|
||||||
|
"create table neighbourhoods(city text, neighbourhood text)", block=True
|
||||||
|
)
|
||||||
|
for i in range(1, 51):
|
||||||
|
for j in range(1, 4):
|
||||||
|
await db.execute_write(
|
||||||
|
"insert into neighbourhoods (city, neighbourhood) values (?, ?)",
|
||||||
|
["City {}".format(i), "Neighbourhood {}".format(j)],
|
||||||
|
block=True,
|
||||||
|
)
|
||||||
|
response = await ds.client.get("/test_facet_size/neighbourhoods.json")
|
||||||
|
data = response.json()
|
||||||
|
assert data["suggested_facets"] == [
|
||||||
|
{
|
||||||
|
"name": "neighbourhood",
|
||||||
|
"toggle_url": "http://localhost/test_facet_size/neighbourhoods.json?_facet=neighbourhood",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
# Bump up _facet_size= to suggest city too
|
||||||
|
response2 = await ds.client.get(
|
||||||
|
"/test_facet_size/neighbourhoods.json?_facet_size=50"
|
||||||
|
)
|
||||||
|
data2 = response2.json()
|
||||||
|
assert sorted(data2["suggested_facets"], key=lambda f: f["name"]) == [
|
||||||
|
{
|
||||||
|
"name": "city",
|
||||||
|
"toggle_url": "http://localhost/test_facet_size/neighbourhoods.json?_facet_size=50&_facet=city",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "neighbourhood",
|
||||||
|
"toggle_url": "http://localhost/test_facet_size/neighbourhoods.json?_facet_size=50&_facet=neighbourhood",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
# Facet by city should return expected number of results
|
||||||
|
response3 = await ds.client.get(
|
||||||
|
"/test_facet_size/neighbourhoods.json?_facet_size=50&_facet=city"
|
||||||
|
)
|
||||||
|
data3 = response3.json()
|
||||||
|
assert len(data3["facet_results"]["city"]["results"]) == 50
|
||||||
|
# Reduce max_returned_rows and check that it's respected
|
||||||
|
ds._settings["max_returned_rows"] = 20
|
||||||
|
response4 = await ds.client.get(
|
||||||
|
"/test_facet_size/neighbourhoods.json?_facet_size=50&_facet=city"
|
||||||
|
)
|
||||||
|
data4 = response4.json()
|
||||||
|
assert len(data4["facet_results"]["city"]["results"]) == 20
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue