label_column option in metadata.json - closes #234

This commit is contained in:
Simon Willison 2018-04-22 10:51:43 -07:00
commit f27cabbaf3
No known key found for this signature in database
GPG key ID: 17E2DEA2588B7F52
5 changed files with 73 additions and 3 deletions

View file

@ -524,7 +524,12 @@ class RowTableShared(BaseView):
if table_info and expand_foreign_keys:
foreign_keys = table_info['foreign_keys']['outgoing']
for fk in foreign_keys:
label_column = tables.get(fk['other_table'], {}).get('label_column')
label_column = (
# First look for metadata.json definition:
table_metadata.get('label_column')
# Fall back to label_column from .inspect() detection:
or tables.get(fk['other_table'], {}).get('label_column')
)
if not label_column:
# No label for this FK
fks[fk['column']] = fk['other_table']

View file

@ -81,7 +81,7 @@ Column units are configured in the metadata like so::
Units are interpreted using Pint_, and you can see the full list of available units in
Pint's `unit registry`_. You can also add `custom units`_ to the metadata, which will be
registered with Pint::
{
"custom_units": [
"decibel = [] = dB"
@ -119,6 +119,29 @@ This will restrict sorting of ``example_table`` to just the ``height`` and
You can also disable sorting entirely by setting ``"sortable_columns": []``
Specifying the label column for a table
---------------------------------------
Datasette's HTML interface attempts to display foreign key references as
labelled hyperlinks. By default, it looks for referenced tables that only have
two columns: a primary key column and one other. It assumes that the second
column should be used as the link label.
If your table has more than two columns you can specify which column should be
used for the link label with the ``label_column`` property::
{
"databases": {
"database1": {
"tables": {
"example_table": {
"label_column": "title"
}
}
}
}
}
Generating a metadata skeleton
------------------------------

View file

@ -97,6 +97,9 @@ METADATA = {
'frequency': 'Hz'
}
},
'custom_foreign_key_label': {
'label_column': 'content2',
},
}
},
}
@ -215,6 +218,12 @@ CREATE TABLE "complex_foreign_keys" (
FOREIGN KEY ("f3") REFERENCES [simple_primary_key](id)
);
CREATE TABLE "custom_foreign_key_label" (
pk varchar(30) primary key,
foreign_key_with_custom_label text,
FOREIGN KEY ("foreign_key_with_custom_label") REFERENCES [primary_key_multiple_columns](id)
);
CREATE TABLE units (
pk integer primary key,
distance int,
@ -241,6 +250,7 @@ INSERT INTO primary_key_multiple_columns VALUES (1, 'hey', 'world');
INSERT INTO foreign_key_references VALUES (1, 1, 1);
INSERT INTO complex_foreign_keys VALUES (1, 1, 2, 1);
INSERT INTO custom_foreign_key_label VALUES (1, 1);
INSERT INTO [table/with/slashes.csv] VALUES (3, 'hey');

View file

@ -17,7 +17,7 @@ def test_homepage(app_client):
assert response.json.keys() == {'test_tables': 0}.keys()
d = response.json['test_tables']
assert d['name'] == 'test_tables'
assert d['tables_count'] == 13
assert d['tables_count'] == 14
def test_database_page(app_client):
@ -80,6 +80,21 @@ def test_database_page(app_client):
'label_column': None,
'primary_keys': ['pk1', 'pk2', 'pk3'],
}, {
'columns': ['pk', 'foreign_key_with_custom_label'],
'name': 'custom_foreign_key_label',
'count': 1,
'hidden': False,
'foreign_keys': {
'incoming': [],
'outgoing': [{
'column': 'foreign_key_with_custom_label',
'other_column': 'id',
'other_table': 'primary_key_multiple_columns'
}],
},
'label_column': None,
'primary_keys': ['pk'],
}, {
'columns': ['pk', 'foreign_key_with_label', 'foreign_key_with_no_label'],
'name': 'foreign_key_references',
'count': 1,
@ -115,6 +130,10 @@ def test_database_page(app_client):
'column': 'id',
'other_column': 'foreign_key_with_no_label',
'other_table': 'foreign_key_references'
}, {
'column': 'id',
'other_column': 'foreign_key_with_custom_label',
'other_table': 'custom_foreign_key_label'
}],
'outgoing': []
},

View file

@ -294,6 +294,19 @@ def test_table_html_foreign_key_links(app_client):
assert expected == [[str(td) for td in tr.select('td')] for tr in table.select('tbody tr')]
def test_table_html_foreign_key_custom_label_column(app_client):
response = app_client.get('/test_tables/custom_foreign_key_label', gather_request=False)
assert response.status == 200
table = Soup(response.body, 'html.parser').find('table')
expected = [
[
'<td class="col-pk"><a href="/test_tables/custom_foreign_key_label/1">1</a></td>',
'<td class="col-foreign_key_with_custom_label"><a href="/test_tables/primary_key_multiple_columns/1">world</a>\xa0<em>1</em></td>',
]
]
assert expected == [[str(td) for td in tr.select('td')] for tr in table.select('tbody tr')]
def test_row_html_compound_primary_key(app_client):
response = app_client.get('/test_tables/compound_primary_key/a,b', gather_request=False)
assert response.status == 200