{"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-849309330", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 849309330, "node_id": "MDEyOklzc3VlQ29tbWVudDg0OTMwOTMzMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-05-27T04:26:10Z", "updated_at": "2021-05-27T04:26:10Z", "author_association": "OWNER", "body": "Demos:\r\n\r\n- https://latest.datasette.io/fixtures/sortable?_nocol=sortable\r\n- https://latest.datasette.io/fixtures/sortable?_col=sortable&_col=text\r\n\r\nAlso try the column cog menu on that page.\r\n\r\nDocumentation: https://docs.datasette.io/en/latest/json_api.html#special-table-arguments", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-846592583", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 846592583, "node_id": "MDEyOklzc3VlQ29tbWVudDg0NjU5MjU4Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-05-23T16:50:45Z", "updated_at": "2021-05-24T17:15:48Z", "author_association": "OWNER", "body": "Still needed:\r\n\r\n- Unit tests\r\n- Documentation\r\n\r\nAnd maybe a UI mechanism for this? I could at least add a \"remove this column\" item to the cog menu on columns.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-846668419", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 846668419, "node_id": "MDEyOklzc3VlQ29tbWVudDg0NjY2ODQxOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-05-24T01:14:27Z", "updated_at": "2021-05-24T01:14:27Z", "author_association": "OWNER", "body": "I tried allowing the removal of `rowid` and got this exception:\r\n```\r\n File \"/Users/simon/Dropbox/Development/datasette/datasette/views/table.py\", line 831, in extra_template\r\n display_columns, display_rows = await self.display_columns_and_rows(\r\n File \"/Users/simon/Dropbox/Development/datasette/datasette/views/table.py\", line 163, in display_columns_and_rows\r\n pk_path = path_from_row_pks(row, pks, not pks, False)\r\n File \"/Users/simon/Dropbox/Development/datasette/datasette/utils/__init__.py\", line 82, in path_from_row_pks\r\n bits = [row[\"rowid\"]]\r\nIndexError: No item with that key\r\n```\r\nI'm going to disable the removal of `rowid` - or indeed any of the primary keys, since they are needed to construct the row permalink.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-846660103", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 846660103, "node_id": "MDEyOklzc3VlQ29tbWVudDg0NjY2MDEwMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-05-24T00:47:00Z", "updated_at": "2021-05-24T00:47:00Z", "author_association": "OWNER", "body": "> Here's a bug: removing the `rowid` column returns an error.\r\n\r\nRemoving the `rowid` column should work. We can continue to show the `Link` column, ensuring users can still navigate to the row page for each row.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-846659272", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 846659272, "node_id": "MDEyOklzc3VlQ29tbWVudDg0NjY1OTI3Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-05-24T00:44:47Z", "updated_at": "2021-05-24T00:44:47Z", "author_association": "OWNER", "body": "I can't think of any good reasons to support passing the same column twice `?col=airline&_col=airline` so I'm going to de-duplicate and silently ignore the second one.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-846627322", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 846627322, "node_id": "MDEyOklzc3VlQ29tbWVudDg0NjYyNzMyMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-05-23T21:31:22Z", "updated_at": "2021-05-23T21:31:22Z", "author_association": "OWNER", "body": "Would it be useful to allow this mechanism to alias columns, for example supporting one of the following:\r\n\r\n- `?_col=airline as name_of_airline`\r\n- `?_col=airline:name_of_airline`\r\n\r\nThis could be handy for renaming columns to match a specific expected JSON output.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-846627163", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 846627163, "node_id": "MDEyOklzc3VlQ29tbWVudDg0NjYyNzE2Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-05-23T21:30:01Z", "updated_at": "2021-05-23T21:30:01Z", "author_association": "OWNER", "body": "Interesting side-effect of this implementation is that you can both control column order and request the same column multiple times:\r\n\r\n`/fivethirtyeight/airline-safety%2Fairline-safety?_col=fatal_accidents_00_14&_col=fatalities_00_14&_col=airline&_col=airline`\r\n\r\n\"fivethirtyeight__airline-safety_airline-safety__56_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": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-846626871", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 846626871, "node_id": "MDEyOklzc3VlQ29tbWVudDg0NjYyNjg3MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-05-23T21:27:36Z", "updated_at": "2021-05-23T21:27:36Z", "author_association": "OWNER", "body": "A better interface for this would be a full list of columns each with a checkbox for making it visible on invisible - this could then be used to apply a bulk change (rather than refreshing the interface after every removed column) and it could also be easily designed to work on narrow mobile screens where the cog icon is not visible.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-846626567", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 846626567, "node_id": "MDEyOklzc3VlQ29tbWVudDg0NjYyNjU2Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-05-23T21:25:19Z", "updated_at": "2021-05-23T21:25:19Z", "author_association": "OWNER", "body": "Here's a bug: removing the `rowid` column returns an error.\r\n\r\n![rowid-bug](https://user-images.githubusercontent.com/9599/119277132-b179ae00-bbd2-11eb-8f2f-e228c7d7c264.gif)\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-846599732", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 846599732, "node_id": "MDEyOklzc3VlQ29tbWVudDg0NjU5OTczMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-05-23T17:46:45Z", "updated_at": "2021-05-23T17:46:45Z", "author_association": "OWNER", "body": "I've changed my mind about forbidding `?_col=` and `?_nocol=` from being applied at the same time - I'm going to come up with a simple resolution rule instead.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-846595473", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 846595473, "node_id": "MDEyOklzc3VlQ29tbWVudDg0NjU5NTQ3Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-05-23T17:13:09Z", "updated_at": "2021-05-23T17:13:09Z", "author_association": "OWNER", "body": "Natalie suggests a quick way to implement \"undo\" would be to add a \"Show all columns\" item to that menu which only appears when at least one column is hidden.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-846595091", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 846595091, "node_id": "MDEyOklzc3VlQ29tbWVudDg0NjU5NTA5MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-05-23T17:09:59Z", "updated_at": "2021-05-23T17:09:59Z", "author_association": "OWNER", "body": "Here's that prototype of a \"Hide this column\" cog menu button:\r\n\r\n![hide](https://user-images.githubusercontent.com/9599/119269916-effd7180-bbae-11eb-92fa-0ef374bda4b8.gif)\r\n\r\nNeed a way to undo that once you've hidden a column - maybe a list of currently hidden columns that lets you un-hide them.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-846592392", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 846592392, "node_id": "MDEyOklzc3VlQ29tbWVudDg0NjU5MjM5Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-05-23T16:49:30Z", "updated_at": "2021-05-23T16:49:44Z", "author_association": "OWNER", "body": "I started looking at this again, inspired by #1326. I have a new diff that works against the latest `main` branch.\r\n\r\n```diff\r\ndiff --git a/datasette/views/table.py b/datasette/views/table.py\r\nindex 4879228..f4b2ee2 100644\r\n--- a/datasette/views/table.py\r\n+++ b/datasette/views/table.py\r\n@@ -64,6 +64,36 @@ class Row:\r\n \r\n \r\n class RowTableShared(DataView):\r\n+ async def columns_to_select(self, db, table, request):\r\n+ table_columns = await db.table_columns(table)\r\n+ if \"_col\" in request.args and \"_nocol\" in request.args:\r\n+ raise DatasetteError(\"Cannot use _col and _nocol at the same time\")\r\n+ if \"_col\" in request.args:\r\n+ new_columns = []\r\n+ for column in request.args.getlist(\"_col\"):\r\n+ if column not in table_columns:\r\n+ raise DatasetteError(\"_col={} is an invalid column\".format(column))\r\n+ new_columns.append(column)\r\n+ return new_columns\r\n+ elif \"_nocol\" in request.args:\r\n+ # Return all columns EXCEPT these\r\n+ bad_columns = [\r\n+ column\r\n+ for column in request.args.getlist(\"_nocol\")\r\n+ if column not in table_columns\r\n+ ]\r\n+ if bad_columns:\r\n+ raise DatasetteError(\r\n+ \"_nocol={} - invalid columns\".format(\", \".join(bad_columns))\r\n+ )\r\n+ return [\r\n+ column\r\n+ for column in table_columns\r\n+ if column not in request.args.getlist(\"_nocol\")\r\n+ ]\r\n+ else:\r\n+ return table_columns\r\n+\r\n async def sortable_columns_for_table(self, database, table, use_rowid):\r\n db = self.ds.databases[database]\r\n table_metadata = self.ds.table_metadata(database, table)\r\n@@ -321,18 +351,16 @@ class TableView(RowTableShared):\r\n )\r\n \r\n pks = await db.primary_keys(table)\r\n- table_column_details = await db.table_column_details(table)\r\n- table_columns = [column.name for column in table_column_details]\r\n-\r\n- select_columns = \", \".join(escape_sqlite(t) for t in table_columns)\r\n+ table_columns = await self.columns_to_select(db, table, request)\r\n+ select_clause = \", \".join(escape_sqlite(t) for t in table_columns)\r\n \r\n use_rowid = not pks and not is_view\r\n if use_rowid:\r\n- select = f\"rowid, {select_columns}\"\r\n+ select = f\"rowid, {select_clause}\"\r\n order_by = \"rowid\"\r\n order_by_pks = \"rowid\"\r\n else:\r\n- select = select_columns\r\n+ select = select_clause\r\n order_by_pks = \", \".join([escape_sqlite(pk) for pk in pks])\r\n order_by = order_by_pks\r\n \r\n@@ -715,6 +743,8 @@ class TableView(RowTableShared):\r\n column = fk[\"column\"]\r\n if column not in columns_to_expand:\r\n continue\r\n+ if column not in columns:\r\n+ continue\r\n expanded_columns.append(column)\r\n # Gather the values\r\n column_index = columns.index(column)\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-550146151", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 550146151, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MDE0NjE1MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-06T05:06:27Z", "updated_at": "2019-11-06T05:06:27Z", "author_association": "OWNER", "body": "I'm going to always include the primary key (or rowid) - otherwise the table view will sometimes not include links to the row pages, which seems bad.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-549591028", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 549591028, "node_id": "MDEyOklzc3VlQ29tbWVudDU0OTU5MTAyOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-04T23:15:28Z", "updated_at": "2019-11-04T23:15:28Z", "author_association": "OWNER", "body": "Demo: visit https://52fa79c.datasette.io/fixtures/roadside_attractions and click \"View and edit SQL\" - you'll be sent to https://52fa79c.datasette.io/fixtures?sql=select+pk%2C+name%2C+address%2C+latitude%2C+longitude+from+roadside_attractions+order+by+pk+limit+101", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/615#issuecomment-549585571", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/615", "id": 549585571, "node_id": "MDEyOklzc3VlQ29tbWVudDU0OTU4NTU3MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-04T22:57:16Z", "updated_at": "2019-11-04T22:57:16Z", "author_association": "OWNER", "body": "First step: stop using `select *` and switch to selecting columns instead. This will also make the `View and edit SQL` button more useful.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 517451234, "label": "?_col= and ?_nocol= support for toggling columns on table view"}, "performed_via_github_app": null}