{"html_url": "https://github.com/simonw/datasette/issues/942#issuecomment-898051645", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/942", "id": 898051645, "node_id": "IC_kwDOBm6k_c41hy49", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-13T00:02:25Z", "updated_at": "2021-08-13T00:02:25Z", "author_association": "OWNER", "body": "And on mobile:\r\n\r\n![5FAF8D73-7199-4BB7-A5B8-9E46DCB4A985](https://user-images.githubusercontent.com/9599/129284817-dc13cbf4-144e-4f4c-8fb7-470602e2eea0.jpeg)\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 681334912, "label": "Support column descriptions in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/942#issuecomment-898050457", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/942", "id": 898050457, "node_id": "IC_kwDOBm6k_c41hymZ", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-12T23:59:53Z", "updated_at": "2021-08-12T23:59:53Z", "author_association": "OWNER", "body": "Documentation: https://docs.datasette.io/en/latest/metadata.html#column-descriptions\r\n\r\nLive demo: https://latest.datasette.io/fixtures/roadside_attractions\r\n\r\n\"fixtures__roadside_attractions__4_rows\"\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 681334912, "label": "Support column descriptions in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/942#issuecomment-898037650", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/942", "id": 898037650, "node_id": "IC_kwDOBm6k_c41hveS", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-12T23:23:54Z", "updated_at": "2021-08-12T23:23:54Z", "author_association": "OWNER", "body": "I like this enough that I'm going to ship it as an alpha and try it out on a couple of live projects.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 681334912, "label": "Support column descriptions in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/942#issuecomment-898037456", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/942", "id": 898037456, "node_id": "IC_kwDOBm6k_c41hvbQ", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-12T23:23:34Z", "updated_at": "2021-08-12T23:23:34Z", "author_association": "OWNER", "body": "Prototype with a `
`:\r\n\r\n\"fixtures__sortable__201_rows\"\r\n\r\n```diff\r\ndiff --git a/datasette/static/app.css b/datasette/static/app.css\r\nindex c6be1e9..bf068fd 100644\r\n--- a/datasette/static/app.css\r\n+++ b/datasette/static/app.css\r\n@@ -836,6 +841,16 @@ svg.dropdown-menu-icon {\r\n background-repeat: no-repeat;\r\n }\r\n \r\n+dl.column-descriptions dt {\r\n+ font-weight: bold;\r\n+}\r\n+dl.column-descriptions dd {\r\n+ padding-left: 1.5em;\r\n+ white-space: pre-wrap;\r\n+ line-height: 1.1em;\r\n+ color: #666;\r\n+}\r\n+\r\n .anim-scale-in {\r\n animation-name: scale-in;\r\n animation-duration: 0.15s;\r\ndiff --git a/datasette/templates/table.html b/datasette/templates/table.html\r\nindex 211352b..466e8a4 100644\r\n--- a/datasette/templates/table.html\r\n+++ b/datasette/templates/table.html\r\n@@ -51,6 +51,14 @@\r\n \r\n {% block description_source_license %}{% include \"_description_source_license.html\" %}{% endblock %}\r\n \r\n+{% if metadata.columns %}\r\n+
\r\n+ {% for column_name, column_description in metadata.columns.items() %}\r\n+
{{ column_name }}
{{ column_description }}
\r\n+ {% endfor %}\r\n+
\r\n+{% endif %}\r\n+\r\n {% if filtered_table_rows_count or human_description_en %}\r\n

{% if filtered_table_rows_count or filtered_table_rows_count == 0 %}{{ \"{:,}\".format(filtered_table_rows_count) }} row{% if filtered_table_rows_count == 1 %}{% else %}s{% endif %}{% endif %}\r\n {% if human_description_en %}{{ human_description_en }}{% endif %}\r\n ```\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 681334912, "label": "Support column descriptions in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/942#issuecomment-898022235", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/942", "id": 898022235, "node_id": "IC_kwDOBm6k_c41hrtb", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-12T22:52:23Z", "updated_at": "2021-08-12T22:52:23Z", "author_association": "OWNER", "body": "I like this. Need to solve for mobile though where the cog menu isn't visible - I think I'll do that with a definition list at the top of the page.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 681334912, "label": "Support column descriptions in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/942#issuecomment-898021895", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/942", "id": 898021895, "node_id": "IC_kwDOBm6k_c41hroH", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-12T22:51:36Z", "updated_at": "2021-08-12T22:51:36Z", "author_association": "OWNER", "body": "Prototype:\r\n\r\n\"fixtures__sortable__201_rows\"\r\n\r\n```diff\r\ndiff --git a/datasette/static/app.css b/datasette/static/app.css\r\nindex c6be1e9..5ca64cb 100644\r\n--- a/datasette/static/app.css\r\n+++ b/datasette/static/app.css\r\n@@ -784,9 +784,14 @@ svg.dropdown-menu-icon {\r\n font-size: 0.7em;\r\n color: #666;\r\n margin: 0;\r\n- padding: 0;\r\n padding: 4px 8px 4px 8px;\r\n }\r\n+.dropdown-menu .dropdown-column-description {\r\n+ margin: 0;\r\n+ color: #666;\r\n+ padding: 4px 8px 4px 8px;\r\n+ max-width: 20em;\r\n+}\r\n .dropdown-menu li {\r\n border-bottom: 1px solid #ccc;\r\n }\r\ndiff --git a/datasette/static/table.js b/datasette/static/table.js\r\nindex 991346d..a903112 100644\r\n--- a/datasette/static/table.js\r\n+++ b/datasette/static/table.js\r\n@@ -9,6 +9,7 @@ var DROPDOWN_HTML = `
\r\n
  • Show not-blank rows
  • \r\n \r\n

    \r\n+

    \r\n
    `;\r\n \r\n var DROPDOWN_ICON_SVG = `\r\n@@ -166,6 +167,14 @@ var DROPDOWN_ICON_SVG = `\r\n
    \r\n {% for column in display_columns %}\r\n- \r\n+ \r\n {% if not column.sortable %}\r\n {{ column.name }}\r\n {% else %}\r\ndiff --git a/datasette/views/table.py b/datasette/views/table.py\r\nindex 456d806..486a613 100644\r\n--- a/datasette/views/table.py\r\n+++ b/datasette/views/table.py\r\n@@ -125,6 +125,7 @@ class RowTableShared(DataView):\r\n \"\"\"Returns columns, rows for specified table - including fancy foreign key treatment\"\"\"\r\n db = self.ds.databases[database]\r\n table_metadata = self.ds.table_metadata(database, table)\r\n+ column_descriptions = table_metadata.get(\"columns\") or {}\r\n column_details = {col.name: col for col in await db.table_column_details(table)}\r\n sortable_columns = await self.sortable_columns_for_table(database, table, True)\r\n pks = await db.primary_keys(table)\r\n@@ -147,6 +148,7 @@ class RowTableShared(DataView):\r\n \"is_pk\": r[0] in pks_for_display,\r\n \"type\": type_,\r\n \"notnull\": notnull,\r\n+ \"description\": column_descriptions.get(r[0]),\r\n }\r\n )\r\n\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 681334912, "label": "Support column descriptions in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/942#issuecomment-897996296", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/942", "id": 897996296, "node_id": "IC_kwDOBm6k_c41hlYI", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-12T22:01:36Z", "updated_at": "2021-08-12T22:01:36Z", "author_association": "OWNER", "body": "I'm going with `\"columns\": {\"name-of-column\": \"description-of-column\"}`.\r\n\r\nIf I decide to make `\"col\"` and `\"nocol\"` available in metadata I'll use those as the keys in the metadata, for consistency with the existing query string parameters.\r\n\r\nI'm OK with having both `\"columns\": ...` and `\"col\": ...` keys in the metadata, even though they could be a tiny bit confusing without the documentation.", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 681334912, "label": "Support column descriptions in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/942#issuecomment-737463116", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/942", "id": 737463116, "node_id": "MDEyOklzc3VlQ29tbWVudDczNzQ2MzExNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-02T20:02:10Z", "updated_at": "2020-12-02T20:03:01Z", "author_association": "OWNER", "body": "My idea is that if you installed my proposed plugin you wouldn't need `metadata.json` at all - your metadata would instead live in a table in the connected SQLite database files - either one table per database (so the metadata can live in the same place as the data) or maybe also in a dedicated separate database file, for if you want to add metadata to an otherwise read-only database.\r\n\r\nThe plugin would then provide a UI for editing that metadata - maybe by configuring some writable canned queries or maybe something more custom than that. Or you could edit the metadata by manually editing the SQLite database file (or loading data into it using a tool like [yaml-to-sqlite](https://github.com/simonw/yaml-to-sqlite)).", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 681334912, "label": "Support column descriptions in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/942#issuecomment-737402392", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/942", "id": 737402392, "node_id": "MDEyOklzc3VlQ29tbWVudDczNzQwMjM5Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-02T18:08:55Z", "updated_at": "2020-12-02T18:08:55Z", "author_association": "OWNER", "body": "SQLite does let you add comments in your CREATE TABLE statements:\r\n```sql\r\nCREATE TABLE something (\r\n id integer primary key, -- integer primary key\r\n created text -- created date as ISO datetime\r\n);\r\n```\r\nBut the only mechanism for reading those back is to retrieve that `CREATE TABLE` block of SQL from the `sqlite_master` table and run a parser against it.\r\n\r\nI've so far resisted adding a SQL syntax parser to Datasette for complexity reasons - though I'm increasingly thinking I'll need to do it at some point.\r\n\r\nI think I'll leave this to plugins. I'm definitely going to build a plugin that lets you store metadata for tables and columns in a SQLite database table, which will then support interactively editing metadata through a UI.\r\n\r\nA plugin which extracts column comments from the SQLite CREATE TABLE comments would be feasible too, if I design the plugin hooks well.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 681334912, "label": "Support column descriptions in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/942#issuecomment-727626657", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/942", "id": 727626657, "node_id": "MDEyOklzc3VlQ29tbWVudDcyNzYyNjY1Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-11-15T19:54:44Z", "updated_at": "2020-11-15T19:54:44Z", "author_association": "OWNER", "body": "This will also benefit from the metadata plugin hook: #860 ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 681334912, "label": "Support column descriptions in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/942#issuecomment-675720040", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/942", "id": 675720040, "node_id": "MDEyOklzc3VlQ29tbWVudDY3NTcyMDA0MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-18T21:05:24Z", "updated_at": "2020-08-18T21:05:24Z", "author_association": "OWNER", "body": "Is `columns` the right key for this in the table metadata block? I might want to use that for initial values for `?_col=` in #615.\r\n\r\nAlternative names:\r\n\r\n- `column_descriptions`\r\n- `column_info`", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 681334912, "label": "Support column descriptions in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/942#issuecomment-675718593", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/942", "id": 675718593, "node_id": "MDEyOklzc3VlQ29tbWVudDY3NTcxODU5Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-18T21:02:11Z", "updated_at": "2020-08-18T21:02:24Z", "author_association": "OWNER", "body": "Easiest solution: if you provide column metadata it gets displayed above the table, something like on https://fivethirtyeight.datasettes.com/fivethirtyeight/antiquities-act%2Factions_under_antiquities_act\r\n\r\n
    \"fivethirtyeight__antiquities-act_actions_under_antiquities_act__344_rows\"\r\n\r\nHTML `title=` tooltips are also added to the table headers, which won't be visible on touch devices but that's OK because the information is visible on the page already.", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 681334912, "label": "Support column descriptions in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/942#issuecomment-675715472", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/942", "id": 675715472, "node_id": "MDEyOklzc3VlQ29tbWVudDY3NTcxNTQ3Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-18T20:55:02Z", "updated_at": "2020-08-18T20:55:02Z", "author_association": "OWNER", "body": "Could display these as tooltips on icons something like this (from the experimental `datasette-inspect-columns` plugin):\r\n\r\n\"fixtures__facetable__15_rows_and_NOAA_tides_second_attempt_-_Jupyter_Notebook\"\r\n\r\nThis would need to take accessibility into account, and would need a different display for the mobile web layout. Need to consider how it will interact with the column menu suggested in #690.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 681334912, "label": "Support column descriptions in metadata.json"}, "performed_via_github_app": null}