{"html_url": "https://github.com/simonw/datasette/issues/617#issuecomment-552253893", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/617", "id": 552253893, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI1Mzg5Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T00:46:42Z", "updated_at": "2021-12-18T01:41:47Z", "author_association": "OWNER", "body": "As noted in https://github.com/simonw/datasette/issues/621#issuecomment-552253208 a common pattern in this method is blocks of code that append new items to the `where_clauses`, `params` and `extra_human_descriptions` arrays. This is a useful refactoring opportunity.\r\n\r\nCode that fits this pattern:\r\n\r\n* The code that builds based on the filters: `where_clauses, params = filters.build_where_clauses(table)` and `human_description_en = filters.human_description_en(extra=extra_human_descriptions)`\r\n* Code that handles `?_where=`: `where_clauses.extend(request.args[\"_where\"])` - though note that this also appends to a `extra_wheres_for_ui` array which nothing else uses\r\n* The `_through=` code, see #621 for details\r\n* The code that deals with `?_search=` FTS\r\n\r\nThe keyset pagination code modifies `where_clauses` and `params` too, but I don't think it's quite going to work with the same abstraction that would cover the above examples.\r\n\r\n[UPDATE December 2021 - this comment became the basis for a new `filters_from_request` plugin hook, see also #473]", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 519613116, "label": "Refactor TableView.data() method"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/595#issuecomment-552327079", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/595", "id": 552327079, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjMyNzA3OQ==", "user": {"value": 647359, "label": "tomchristie"}, "created_at": "2019-11-11T07:34:27Z", "updated_at": "2019-11-11T07:34:27Z", "author_association": "NONE", "body": "> Glitch has been upgraded to Python 3.7.\r\n\r\nWhoop! \ud83e\udd73 \u2728 ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 506300941, "label": "bump uvicorn to 0.9.0 to be Python-3.8 friendly"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/623#issuecomment-552281217", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/623", "id": 552281217, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI4MTIxNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T03:40:59Z", "updated_at": "2019-11-11T03:40:59Z", "author_association": "OWNER", "body": "That did the trick - still some warnings now but they are all in dependencies:\r\n```\r\n=============================== warnings summary ===============================\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/pint/compat/chainmap.py:16\r\n\r\n /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/pint/compat/chainmap.py:16: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.9 it will stop working\r\n\r\n from collections import MutableMapping\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/pint/util.py:21\r\n\r\n /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/pint/util.py:21: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.9 it will stop working\r\n\r\n from collections import Mapping\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:17\r\n\r\n /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:17: DeprecationWarning: \"@coroutine\" decorator is deprecated since Python 3.8, use \"async def\" instead\r\n\r\n def __anext__(self):\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:63\r\n\r\n /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:63: DeprecationWarning: \"@coroutine\" decorator is deprecated since Python 3.8, use \"async def\" instead\r\n\r\n def __iter__(self):\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:72\r\n\r\n /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:72: DeprecationWarning: \"@coroutine\" decorator is deprecated since Python 3.8, use \"async def\" instead\r\n\r\n def __anext__(self):\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:77\r\n\r\n /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:77: DeprecationWarning: \"@coroutine\" decorator is deprecated since Python 3.8, use \"async def\" instead\r\n\r\n def __aenter__(self):\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:82\r\n\r\n /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:82: DeprecationWarning: \"@coroutine\" decorator is deprecated since Python 3.8, use \"async def\" instead\r\n\r\n def __aexit__(self, exc_type, exc, tb):\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:91\r\n\r\n /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:91: DeprecationWarning: \"@coroutine\" decorator is deprecated since Python 3.8, use \"async def\" instead\r\n\r\n def __aexit__(self, exc_type, exc_val, exc_tb):\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33\r\n\r\n /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33: DeprecationWarning: \"@coroutine\" decorator is deprecated since Python 3.8, use \"async def\" instead\r\n\r\n def method(self, *args, **kwargs):\r\n\r\n/home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/__init__.py:27\r\n\r\n /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/__init__.py:27: DeprecationWarning: \"@coroutine\" decorator is deprecated since Python 3.8, use \"async def\" instead\r\n\r\n def _open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None,\r\n\r\n-- Docs: https://docs.pytest.org/en/latest/warnings.html\r\n\r\n================== 379 passed, 54 warnings in 201.62 seconds ===================\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 520718056, "label": "Test against Python 3.8 in Travis"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/623#issuecomment-552279522", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/623", "id": 552279522, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI3OTUyMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T03:31:17Z", "updated_at": "2019-11-11T03:31:17Z", "author_association": "OWNER", "body": "`================= 379 passed, 4332 warnings in 195.71 seconds ==================`\r\n\r\nI think all of those warnings are the same:\r\n```\r\n /home/travis/build/simonw/datasette/datasette/tracer.py:17: DeprecationWarning: Task.current_task() is deprecated, use asyncio.current_task() instead\r\n return id(asyncio.Task.current_task(loop=loop))\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 520718056, "label": "Test against Python 3.8 in Travis"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/501#issuecomment-552278216", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/501", "id": 552278216, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI3ODIxNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T03:23:29Z", "updated_at": "2019-11-11T03:23:29Z", "author_association": "OWNER", "body": "Closing this so I can do a clean single commit instead.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 452901999, "label": "Test against Python 3.8-dev using Travis"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/501#issuecomment-552278039", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/501", "id": 552278039, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI3ODAzOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T03:22:36Z", "updated_at": "2019-11-11T03:22:36Z", "author_association": "OWNER", "body": "Wow! `= 379 passed, 4332 warnings in 196.92 seconds =` - that's a lot of warnings.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 452901999, "label": "Test against Python 3.8-dev using Travis"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/501#issuecomment-552276422", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/501", "id": 552276422, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI3NjQyMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T03:13:52Z", "updated_at": "2019-11-11T03:13:52Z", "author_association": "OWNER", "body": "Dropping 3.5 compatibility will help here #622 ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 452901999, "label": "Test against Python 3.8-dev using Travis"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/404#issuecomment-552276277", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/404", "id": 552276277, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI3NjI3Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T03:13:09Z", "updated_at": "2019-11-11T03:13:09Z", "author_association": "OWNER", "body": "#622 will drop 3.5 support.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 403499298, "label": "Experiment: run Jinja in async mode"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/594#issuecomment-552276247", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/594", "id": 552276247, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI3NjI0Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T03:13:00Z", "updated_at": "2019-11-11T03:13:00Z", "author_association": "OWNER", "body": "#622", "reactions": "{\"total_count\": 1, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 1, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 506297048, "label": "upgrade to uvicorn-0.9 to be Python-3.8 friendly"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/595#issuecomment-552276237", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/595", "id": 552276237, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI3NjIzNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T03:12:56Z", "updated_at": "2019-11-11T03:12:56Z", "author_association": "OWNER", "body": "#622", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 506300941, "label": "bump uvicorn to 0.9.0 to be Python-3.8 friendly"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/595#issuecomment-552275668", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/595", "id": 552275668, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI3NTY2OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T03:09:43Z", "updated_at": "2019-11-11T03:09:43Z", "author_association": "OWNER", "body": "Glitch has been upgraded to Python 3.7. I think I'm happy to drop 3.5 support now - users who want Python 3.5 can get it by installing `datasette==0.30.2`", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 506300941, "label": "bump uvicorn to 0.9.0 to be Python-3.8 friendly"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/181#issuecomment-552275451", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/181", "id": 552275451, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI3NTQ1MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T03:08:25Z", "updated_at": "2019-11-11T03:08:25Z", "author_association": "OWNER", "body": "Closing this because this feature was shipped in #592 ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 289425975, "label": "add \"format sql\" button to query page, uses sql-formatter"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/617#issuecomment-552254753", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/617", "id": 552254753, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI1NDc1Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T00:54:51Z", "updated_at": "2019-11-11T00:54:51Z", "author_association": "OWNER", "body": "That `table_filter()` plugin hook should probably be renamed though, since it could now apply to the regular custom SQL view as well as the table view.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 519613116, "label": "Refactor TableView.data() method"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/617#issuecomment-552254238", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/617", "id": 552254238, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI1NDIzOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T00:49:57Z", "updated_at": "2019-11-11T00:51:35Z", "author_association": "OWNER", "body": "I experimented with a `table_filter()` plugin hook a while ago which looks very much like the abstraction I'm now talking about here: https://github.com/simonw/datasette/commit/5116c4ec8aed5091e1f75415424b80f613518dc6 - more details here: https://simonwillison.net/2018/Aug/6/russian-facebook-ads/#Weird_implementation_details_106", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 519613116, "label": "Refactor TableView.data() method"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/621#issuecomment-552253208", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/621", "id": 552253208, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI1MzIwOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T00:39:57Z", "updated_at": "2019-11-11T00:39:57Z", "author_association": "OWNER", "body": "This is a nice opportunity to help with the refactoring of the table view in #617 - the above code snippet takes the request, looks at the `_through=` parameters and appends things to the `where_clauses`, `params` and `extra_human_descriptions` lists. I can factor that out into a separate private method on `TableView` and use that as a pattern for further refactoring.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 520681725, "label": "Syntax for ?_through= that works as a form field"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/621#issuecomment-552251645", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/621", "id": 552251645, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI1MTY0NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T00:23:56Z", "updated_at": "2019-11-11T00:33:31Z", "author_association": "OWNER", "body": "Current syntax: https://datasette.readthedocs.io/en/stable/json_api.html#special-table-arguments\r\n\r\n`/?_through={\"table\":\"roadside_attraction_characteristics\",\"column\":\"characteristic_id\",\"value\":\"1\"}`\r\n\r\nDemo: https://latest.datasette.io/fixtures/roadside_attractions?_through={%22table%22:%22roadside_attraction_characteristics%22,%22column%22:%22characteristic_id%22,%22value%22:%221%22}\r\n\r\nThe alternative syntax for that could be: \r\n\r\n`https://latest.datasette.io/fixtures/roadside_attractions?_through.roadside_attraction_characteristics.characteristic_id=1`", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 520681725, "label": "Syntax for ?_through= that works as a form field"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/621#issuecomment-552251666", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/621", "id": 552251666, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI1MTY2Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T00:24:09Z", "updated_at": "2019-11-11T00:32:49Z", "author_association": "OWNER", "body": "Here's the current code:\r\n\r\nhttps://github.com/simonw/datasette/blob/28c4a6db5b5e512db630d7ba6127196185de67c7/datasette/views/table.py#L316-L348", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 520681725, "label": "Syntax for ?_through= that works as a form field"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/620#issuecomment-552252074", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/620", "id": 552252074, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI1MjA3NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T00:28:28Z", "updated_at": "2019-11-11T00:30:53Z", "author_association": "OWNER", "body": "So for foreign key definitions it could look like this:\r\n\r\n`/db/table?_fk.article_id=articles.id`\r\n\r\nOr for columns and table names that themselves contain dots it could be:\r\n\r\n`/db/table?_fk.article_id={\"table\":\"articles\",\"column\":\"id\"}`\r\n\r\nThe value (before the =) is unambiguous -it's `?fk.XXX` where XXX could be a column name that includes periods without breaking anything.\r\n\r\nAdded bonus: if you're referencing another table's single primary key you can omit the `.id` entirely (since it can be automatically detected) - so you could do `?_fk.article_id=articles`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 520667773, "label": "Mechanism for indicating foreign key relationships in the table and query page URLs"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/620#issuecomment-552252199", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/620", "id": 552252199, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI1MjE5OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T00:29:36Z", "updated_at": "2019-11-11T00:29:36Z", "author_association": "OWNER", "body": "This new `?_fk.column_name=` syntax makes me wonder if the various filters should be `?colname.contains=x` rather than `?colname__contains=x` - but that's a conversation for another time.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 520667773, "label": "Mechanism for indicating foreign key relationships in the table and query page URLs"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/620#issuecomment-552251831", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/620", "id": 552251831, "node_id": "MDEyOklzc3VlQ29tbWVudDU1MjI1MTgzMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-11-11T00:25:58Z", "updated_at": "2019-11-11T00:25:58Z", "author_association": "OWNER", "body": "There are three pieces of information that need to be described here: the column, the other table and the other table column.\r\n\r\nWe already have a piece of API design that is similar to this: the `_through=` parameter, which looks like this:\r\n\r\n`?_through={\"table\":\"m2m_characteristics\",\"column\":\"characteristic_id\",\"value\":\"1\"}`\r\n\r\nI'm rethinking this syntax in #621 though to support a non-JSON variant that looks more like this:\r\n\r\n`?_through.roadside_attraction_characteristics.characteristic_id=1`", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 520667773, "label": "Mechanism for indicating foreign key relationships in the table and query page URLs"}, "performed_via_github_app": null}