diff --git a/datasette/app.py b/datasette/app.py index 6b143785..0560193e 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -84,6 +84,12 @@ class BaseView(RenderMixin): self.page_size = datasette.page_size self.max_returned_rows = datasette.max_returned_rows + def table_metadata(self, database, table): + "Fetch table-specific metadata." + return self.ds.metadata.get( + 'databases', {} + ).get(database, {}).get('tables', {}).get(table, {}) + def options(self, request, *args, **kwargs): r = response.text('ok') if self.ds.cors: @@ -449,11 +455,6 @@ class DatabaseDownload(BaseView): class RowTableShared(BaseView): - def table_metadata(self, database, table): - return self.ds.metadata.get( - 'databases', {} - ).get(database, {}).get('tables', {}).get(table, {}) - def sortable_columns_for_table(self, name, table, use_rowid): table_metadata = self.table_metadata(name, table) if 'sortable_columns' in table_metadata: @@ -890,6 +891,7 @@ class TableView(RowTableShared): 'filtered_table_rows_count': filtered_table_rows_count, 'columns': columns, 'primary_keys': pks, + 'units': self.table_metadata(name, table).get('units', {}), 'query': { 'sql': sql, 'params': params, @@ -959,6 +961,7 @@ class RowView(RowTableShared): 'columns': columns, 'primary_keys': pks, 'primary_key_values': pk_values, + 'units': self.table_metadata(name, table).get('units', {}) } if 'foreign_key_tables' in (request.raw_args.get('_extras') or '').split(','): diff --git a/datasette/cli.py b/datasette/cli.py index 5744d00a..0fde53cf 100644 --- a/datasette/cli.py +++ b/datasette/cli.py @@ -160,6 +160,7 @@ def skeleton(files, metadata, sqlite_extensions): 'license_url': None, 'source': None, 'source_url': None, + 'units': {} } for table_name in (info.get('tables') or {}) } } diff --git a/docs/metadata.rst b/docs/metadata.rst index 3c842634..0f94311c 100644 --- a/docs/metadata.rst +++ b/docs/metadata.rst @@ -55,6 +55,35 @@ You can also provide metadata at the per-database or per-table level, like this: Each of the top-level metadata fields can be used at the database and table level. +Specifying units for a column +----------------------------- + +Datasette supports attaching units to a column, which will be used when displaying +values from that column. SI prefixes will be used where appropriate. + +Column units are configured in the metadata like so:: + + { + "databases": { + "database1": { + "tables": { + "example_table": { + "units": { + "column1": "metres", + "column2": "Hz" + } + } + } + } + } + } + +Units are interpreted using Pint_, and you can see the full list of available units in +Pint's `unit registry`_. + +.. _Pint: https://pint.readthedocs.io/ +.. _unit registry: https://github.com/hgrecco/pint/blob/master/pint/default_en.txt + Setting which columns can be used for sorting --------------------------------------------- @@ -119,7 +148,8 @@ This will create a ``metadata.json`` file looking something like this:: "license": null, "license_url": null, "source": null, - "source_url": null + "source_url": null, + "units": {} } } },