{"html_url": "https://github.com/simonw/datasette/issues/1#issuecomment-338523957", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1", "id": 338523957, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODUyMzk1Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T01:09:05Z", "updated_at": "2017-10-24T02:42:12Z", "author_association": "OWNER", "body": "I also need to solve for weird primary keys. If it\u2019s a single integer or a single char field that\u2019s easy. But what if it is a compound key with more than one chat field? What delimiter can I use that will definitely be safe?\r\n\r\nLet\u2019s say I use hyphen. Now I need to find a durable encoding for any hyphens that might exist in the key fields themselves.\r\n\r\nHow about I use URLencoding for every non-alpha-numeric character? That will turn hyphens into (I think) %2D. It should also solve for unicode characters, but it means the vast majority of keys (integers) will display neatly, including a compound key of eg 5678-345\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": 267513424, "label": "Addressable pages for every row in a table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1#issuecomment-338524454", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1", "id": 338524454, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODUyNDQ1NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T01:15:24Z", "updated_at": "2017-10-23T01:15:24Z", "author_association": "OWNER", "body": "Table rendering logic needs to detect the primary key field and turn it into a hyperlink. If there is a compound primary key it should add an extra column at the start of the table which displays the compound key as a link", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267513424, "label": "Addressable pages for every row in a table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1#issuecomment-338857568", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1", "id": 338857568, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODg1NzU2OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T02:57:12Z", "updated_at": "2017-10-24T02:57:12Z", "author_association": "OWNER", "body": "I can find the primary keys using:\r\n\r\n PRAGMA table_info(myTable)\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267513424, "label": "Addressable pages for every row in a table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1#issuecomment-338861511", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1", "id": 338861511, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODg2MTUxMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T03:24:17Z", "updated_at": "2017-10-24T03:24:17Z", "author_association": "OWNER", "body": "Some tables won't have primary keys, in which case I won't generate pages for individual records.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267513424, "label": "Addressable pages for every row in a table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1#issuecomment-338872286", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1", "id": 338872286, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODg3MjI4Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T04:46:06Z", "updated_at": "2017-10-24T04:46:06Z", "author_association": "OWNER", "body": "I'm going to use `,` as the separator between elements of a compound primary key. If those elements themselves include a comma I will use `%2C` in its place.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267513424, "label": "Addressable pages for every row in a table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1#issuecomment-338882207", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1", "id": 338882207, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODg4MjIwNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T05:56:04Z", "updated_at": "2017-10-24T05:56:04Z", "author_association": "OWNER", "body": "Next step: generate links to these.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267513424, "label": "Addressable pages for every row in a table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/3#issuecomment-338526148", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/3", "id": 338526148, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODUyNjE0OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T01:35:17Z", "updated_at": "2017-10-23T01:35:17Z", "author_association": "OWNER", "body": "https://github.com/ahupp/python-magic/blob/master/README.md", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267515678, "label": "Make individual column valuables addressable, with smart content types"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/4#issuecomment-338530389", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/4", "id": 338530389, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODUzMDM4OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T02:15:41Z", "updated_at": "2017-10-23T02:15:41Z", "author_association": "OWNER", "body": "This means I need a good solution for these compile time options while running in development mode \r\n ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267515836, "label": "Make URLs immutable"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/4#issuecomment-338530480", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/4", "id": 338530480, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODUzMDQ4MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T02:16:33Z", "updated_at": "2017-10-23T02:16:33Z", "author_association": "OWNER", "body": " How about when the service starts up it checks for a compile.json file and, if it is missing, creates it using the same code we run at compile time normally ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267515836, "label": "Make URLs immutable"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/4#issuecomment-338531827", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/4", "id": 338531827, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODUzMTgyNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T02:28:31Z", "updated_at": "2017-10-23T02:29:05Z", "author_association": "OWNER", "body": "Many of the applications I want to implement with this would benefit from having permanent real URLs.\r\n\r\nSo let\u2019s have both. The sha1 urls will serve far future cache headers (and an etag derived from their path). The non sha1 URLs will serve 302 uncached redirects to the sha1 locations.\r\n\r\nWe will have a setting that lets people opt out of this behavior.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267515836, "label": "Make URLs immutable"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/4#issuecomment-338789734", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/4", "id": 338789734, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODc4OTczNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T20:40:25Z", "updated_at": "2017-10-23T21:10:19Z", "author_association": "OWNER", "body": "URL design:\r\n\r\n /database/table.json - redirects to /database-6753f4a/table.json\r\n\r\nSo we always redirect to the version with the truncated hash in the URL.\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267515836, "label": "Make URLs immutable"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/4#issuecomment-338797522", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/4", "id": 338797522, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODc5NzUyMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T21:09:33Z", "updated_at": "2017-10-23T21:09:33Z", "author_association": "OWNER", "body": "https://stackoverflow.com/a/18134919/6083 is a good answer about how many characters of the hash are needed to be unique. I say we default to 7 characters, like git does - but allow extras to be configured.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267515836, "label": "Make URLs immutable"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/4#issuecomment-338799438", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/4", "id": 338799438, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODc5OTQzOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T21:17:25Z", "updated_at": "2017-10-23T21:17:25Z", "author_association": "OWNER", "body": "Can I take advantage of HTTP/2 so even if you get redirected I start serving you the correct resource straight away?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267515836, "label": "Make URLs immutable"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/4#issuecomment-338804173", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/4", "id": 338804173, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODgwNDE3Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T21:36:37Z", "updated_at": "2017-10-23T21:36:37Z", "author_association": "OWNER", "body": "Looks like the easiest way to implement HTTP/2 server push today is to run behind Cloudflare and use this:\r\n\r\n Link: ; rel=preload; as=script\r\n\r\nhttps://blog.cloudflare.com/announcing-support-for-http-2-server-push-2/\r\n\r\nHere's the W3C draft: https://w3c.github.io/preload/\r\n\r\nFrom https://w3c.github.io/preload/#as-attribute it looks like I should use `as=fetch` if the content is intended for consumption by fetch() or XMLHTTPRequest.\r\n\r\nUnclear if I should throw `as=fetch crossorigin` in there. Need to experiment on that.\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267515836, "label": "Make URLs immutable"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/4#issuecomment-338806718", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/4", "id": 338806718, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODgwNjcxOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T21:47:53Z", "updated_at": "2017-10-23T21:47:53Z", "author_association": "OWNER", "body": "Here's what the homepage of cloudflare.com does (with newlines added within the link header for clarity):\r\n\r\n $ curl -i 'https://www.cloudflare.com/' \r\n HTTP/1.1 200 OK\r\n Date: Mon, 23 Oct 2017 21:45:58 GMT\r\n Content-Type: text/html; charset=utf-8\r\n Transfer-Encoding: chunked\r\n Connection: keep-alive\r\n link:\r\n ; rel=preload; as=style,\r\n ; rel=preload; as=style,\r\n ; rel=preload,\r\n ; rel=preload,\r\n ; rel=preload; as=video,\r\n ; rel=preload; as=video,\r\n ; rel=preload; as=video,\r\n ; rel=preload; as=video,\r\n ; rel=preload; as=video,\r\n ; rel=preload; as=image\r\n\r\nThe original header looked like this:\r\n\r\n link: ; rel=preload; as=style, ; rel=preload; as=style, ; rel=preload, ; rel=preload, ; rel=preload; as=video, ; rel=preload; as=video, ; rel=preload; as=video, ; rel=preload; as=video, ; rel=preload; as=video, ; rel=preload; as=image\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": 267515836, "label": "Make URLs immutable"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/5#issuecomment-338524857", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/5", "id": 338524857, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODUyNDg1Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T01:20:30Z", "updated_at": "2017-10-23T01:20:30Z", "author_association": "OWNER", "body": "https://stackoverflow.com/a/14468878/6083\r\n\r\nLooks like I should order by compound primary key and implement cursor-based pagination.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267516066, "label": "Implement sensible query pagination"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/5#issuecomment-339027711", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/5", "id": 339027711, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTAyNzcxMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T15:21:30Z", "updated_at": "2017-10-24T15:21:30Z", "author_association": "OWNER", "body": "I have code to detect primary keys on tables... but what should I do for tables that lack primary keys? How should I even sort them?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267516066, "label": "Implement sensible query pagination"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/5#issuecomment-339028979", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/5", "id": 339028979, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTAyODk3OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T15:25:08Z", "updated_at": "2017-10-24T15:25:08Z", "author_association": "OWNER", "body": "Looks like I can use the SQLite specific \u201crowid\u201d in that case. It isn\u2019t guaranteed to stay consistent across a VACUUM but that\u2019s ok because we are immutable anyway.\r\n\r\n https://www.sqlite.org/lang_createtable.html#rowid", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267516066, "label": "Implement sensible query pagination"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/7#issuecomment-338853083", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/7", "id": 338853083, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODg1MzA4Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T02:27:25Z", "updated_at": "2017-10-24T02:27:25Z", "author_association": "OWNER", "body": "Fixed in 9d219140694551453bfa528e0624919eb065f9d6", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267516650, "label": "Framework where by every page is JSON plus a template"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/8#issuecomment-338697223", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/8", "id": 338697223, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODY5NzIyMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T15:28:11Z", "updated_at": "2017-10-23T15:28:11Z", "author_association": "OWNER", "body": "Now returning this:\r\n\r\n {\r\n \"error\": \"attempt to write a readonly database\",\r\n \"ok\": false\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": 267517314, "label": "Attempting an INSERT or UPDATE should return a sane error message"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/9#issuecomment-338863155", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/9", "id": 338863155, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODg2MzE1NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T03:36:58Z", "updated_at": "2017-10-24T03:36:58Z", "author_association": "OWNER", "body": "I\u2019m going to use py.test and start with all tests in a single tests.py module", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267517348, "label": "Initial test suite"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/9#issuecomment-338882110", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/9", "id": 338882110, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODg4MjExMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T05:55:33Z", "updated_at": "2017-10-24T05:55:33Z", "author_association": "OWNER", "body": "Well, I've started it at least.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267517348, "label": "Initial test suite"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/10#issuecomment-341938424", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/10", "id": 341938424, "node_id": "MDEyOklzc3VlQ29tbWVudDM0MTkzODQyNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-04T23:48:57Z", "updated_at": "2017-11-04T23:48:57Z", "author_association": "OWNER", "body": "Done: https://github.com/simonw/stateless-datasets/commit/edaa10587e60946e0c1935333f6b79553db33798", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267517381, "label": "Set up Travis"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/11#issuecomment-338530704", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/11", "id": 338530704, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODUzMDcwNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T02:18:36Z", "updated_at": "2017-10-23T02:18:36Z", "author_association": "OWNER", "body": "Needed by https://github.com/simonw/stateless-datasets/issues/4#issuecomment-338530389", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267522549, "label": "Code that generates compile-time properties about the database "}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/12#issuecomment-348245757", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/12", "id": 348245757, "node_id": "MDEyOklzc3VlQ29tbWVudDM0ODI0NTc1Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-30T16:39:45Z", "updated_at": "2017-11-30T16:39:45Z", "author_association": "OWNER", "body": "It is now possible to over-ride templates on a per-database / per-row or per-\r\ntable basis.\r\n\r\nWhen you access e.g. `/mydatabase/mytable` Datasette will look for the following:\r\n\r\n - table-mydatabase-mytable.html\r\n - table.html\r\n\r\nIf you provided a `--template-dir` argument to datasette serve it will look in\r\nthat directory first.\r\n\r\nThe lookup rules are as follows:\r\n\r\n Index page (/):\r\n index.html\r\n\r\n Database page (/mydatabase):\r\n database-mydatabase.html\r\n database.html\r\n\r\n Table page (/mydatabase/mytable):\r\n table-mydatabase-mytable.html\r\n table.html\r\n\r\n Row page (/mydatabase/mytable/id):\r\n row-mydatabase-mytable.html\r\n row.html\r\n\r\nIf a table name has spaces or other unexpected characters in it, the template\r\nfilename will follow the same rules as our custom `` CSS classes\r\nintroduced in 8ab3a16 - for example, a table called \"Food Trucks\"\r\nwill attempt to load the following templates:\r\n\r\n table-mydatabase-Food-Trucks-399138.html\r\n table.html\r\n\r\nIt is possible to extend the default templates using Jinja template\r\ninheritance. If you want to customize EVERY row template with some additional\r\ncontent you can do so by creating a `row.html` template like this:\r\n\r\n {% extends \"default:row.html\" %}\r\n\r\n {% block content %}\r\n

EXTRA HTML AT THE TOP OF THE CONTENT BLOCK

\r\n

This line renders the original block:

\r\n {{ super() }}\r\n {% endblock %}\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267523511, "label": "Make it so you can override templates"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/13#issuecomment-344462608", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/13", "id": 344462608, "node_id": "MDEyOklzc3VlQ29tbWVudDM0NDQ2MjYwOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-15T02:04:51Z", "updated_at": "2017-11-15T02:04:51Z", "author_association": "OWNER", "body": "Fixed in https://github.com/simonw/datasette/commit/8252daa4c14d73b4b69e3f2db4576bb39d73c070 - thanks, @tomdyson!", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267542338, "label": "Add a syntax highlighting SQL editor"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-343675165", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 343675165, "node_id": "MDEyOklzc3VlQ29tbWVudDM0MzY3NTE2NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-11T16:07:10Z", "updated_at": "2017-11-11T16:07:10Z", "author_association": "OWNER", "body": "The plugin system can also allow alternative providers for the `publish` command - e.g. maybe hook up hyper.sh as an option for publishing containers.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-344438724", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 344438724, "node_id": "MDEyOklzc3VlQ29tbWVudDM0NDQzODcyNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-14T23:47:54Z", "updated_at": "2017-11-14T23:47:54Z", "author_association": "OWNER", "body": "Plugins should be able to interact with the build step. This would give plugins an opportunity to modify the SQL databases and help prepare them for serving - for example, a full-text search plugin might create additional FTS tables, or a mapping plugin might pre-calculate a bunch of geohashes for tables that have latitude/longitude values. Plugins could really take advantage of the immutable nature of the dataset here.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-345067498", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 345067498, "node_id": "MDEyOklzc3VlQ29tbWVudDM0NTA2NzQ5OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-16T21:25:32Z", "updated_at": "2017-11-16T21:26:22Z", "author_association": "OWNER", "body": "For visualizations, Google Maps should be made available as a plugin. The default visualizations can use Leaflet and Open Street Map, but there's no reason to not make Google Maps available as a plugin, especially if the plugin can provide a mechanism for configuring the necessary API key.\r\n\r\nI'm particularly excited in the Google Maps heatmap visualization https://developers.google.com/maps/documentation/javascript/heatmaplayer as seen on http://mochimachine.org/wasteland/", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-345893877", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 345893877, "node_id": "MDEyOklzc3VlQ29tbWVudDM0NTg5Mzg3Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-21T02:11:27Z", "updated_at": "2017-11-21T02:11:27Z", "author_association": "OWNER", "body": "http://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins Is pretty good ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-346244871", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 346244871, "node_id": "MDEyOklzc3VlQ29tbWVudDM0NjI0NDg3MQ==", "user": {"value": 21148, "label": "jacobian"}, "created_at": "2017-11-22T05:06:30Z", "updated_at": "2017-11-22T05:06:30Z", "author_association": "CONTRIBUTOR", "body": "I'd also suggest taking a look at [stevedore](https://docs.openstack.org/stevedore/latest/), which has a ton of tools for doing plugin stuff. I've had good luck with it in the past.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-346406009", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 346406009, "node_id": "MDEyOklzc3VlQ29tbWVudDM0NjQwNjAwOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-22T16:39:08Z", "updated_at": "2017-11-22T16:39:08Z", "author_association": "OWNER", "body": "Oh thanks, that definitely looks like an interesting option.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-381442233", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 381442233, "node_id": "MDEyOklzc3VlQ29tbWVudDM4MTQ0MjIzMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-04-15T22:13:06Z", "updated_at": "2018-04-15T22:13:06Z", "author_association": "OWNER", "body": "I started a thread on Twitter asking people for good examples of Python projects with a strong plugin ecosystem: https://twitter.com/simonw/status/985377670388105216\r\n\r\nThe most impressive example that came back was pytest - which now has nearly 400 plugins: https://plugincompat.herokuapp.com/\r\n\r\nThe pytest plugin infrastructure is available as an independent package called pluggy - which appears to offer everything I need for Datasette. I'm going to give that a go and see how well it works: https://pluggy.readthedocs.io/en/latest/", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-381442494", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 381442494, "node_id": "MDEyOklzc3VlQ29tbWVudDM4MTQ0MjQ5NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-04-15T22:17:59Z", "updated_at": "2018-04-15T22:17:59Z", "author_association": "OWNER", "body": "Datasette 1.0 will be the release of Datasette that attempts to provide a stable plugin API: https://github.com/simonw/datasette/milestone/7\r\n\r\nThere's a lot of work to be done before then, but as a starting point I'm going to support two very simple extension mechanisms:\r\n\r\n* Template system plugins - where the hook gets passed the Jinja environment and can freely register new template tags and filters\r\n* SQLite connection plugins - where the hook gets passed a new SQLite connection and can register custom SQLite functions\r\n\r\nThe template system hook will go near here:\r\n\r\nhttps://github.com/simonw/datasette/blob/efbb4e83374a2c795e436c72fa79f70da72309b8/datasette/app.py#L1225-L1228\r\n\r\nThe SQLite connection hook will go near here:\r\n\r\nhttps://github.com/simonw/datasette/blob/efbb4e83374a2c795e436c72fa79f70da72309b8/datasette/app.py#L1094-L1098\r\n\r\nThese two feel simple enough that I'm not worried that I might design an API that I later regret.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-381443728", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 381443728, "node_id": "MDEyOklzc3VlQ29tbWVudDM4MTQ0MzcyOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-04-15T22:39:00Z", "updated_at": "2018-04-15T22:39:00Z", "author_association": "OWNER", "body": "Tox is a good example of a project that uses pluggy in the way I want to use it (function hooks rather than classes): https://github.com/tox-dev/tox/blob/master/tox/hookspecs.py", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-381446392", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 381446392, "node_id": "MDEyOklzc3VlQ29tbWVudDM4MTQ0NjM5Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-04-15T23:22:40Z", "updated_at": "2018-04-16T05:25:57Z", "author_association": "OWNER", "body": "OK, from that prototype in f2720b0c6b7172ebe8820 it looks like pluggy provides a solid path forward.\r\n\r\nNext steps:\r\n\r\n- [x] Build a demo plugin that uses setuptools entrypoints to register with the `datasette` plugin manager via pluggy\r\n- [x] Figure out a mechanism for registering plugins without first needing to publish them to PyPI. Can I load plugins from a special `plugins/` directory similar to the `--template-dir=templates/` option already supported by Datasette? #211", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-381446511", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 381446511, "node_id": "MDEyOklzc3VlQ29tbWVudDM4MTQ0NjUxMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-04-15T23:25:04Z", "updated_at": "2018-04-15T23:25:04Z", "author_association": "OWNER", "body": "Here's a demo of the `convert_units()` SQL function I prototyped in f2720b0c6b7172ebe88\r\n\r\n![2018-04-15 at 4 23 pm](https://user-images.githubusercontent.com/9599/38784633-8c43821e-40c9-11e8-97dd-697755a0f858.png)\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-381446906", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 381446906, "node_id": "MDEyOklzc3VlQ29tbWVudDM4MTQ0NjkwNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-04-15T23:31:58Z", "updated_at": "2018-04-15T23:34:10Z", "author_association": "OWNER", "body": "Once I've got the plugins mechanism stable and people start releasing plugins it would be useful to have a dedicated Trove classifier on PyPI for Datasette plugins - `Framework :: Datasette` for example.\r\n\r\nThis would help me build a Datasette equivalent of the http://plugincompat.herokuapp.com/ site, which works by scanning PyPI for items with the ``Framework :: Pytest`` classifier:\r\n\r\nhttps://github.com/pytest-dev/plugincompat/blob/8bdf1a6fb82807091ece0c68c196103ee8270194/update_index.py#L52-L53\r\n\r\nIt looks like the mechanism for requesting new PyPI classifiers is to file a ticket against warehouse, like these ones: https://github.com/pypa/warehouse/issues/3570 and https://github.com/pypa/warehouse/issues/2881", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-381450394", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 381450394, "node_id": "MDEyOklzc3VlQ29tbWVudDM4MTQ1MDM5NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-04-16T00:27:23Z", "updated_at": "2018-04-16T00:27:23Z", "author_association": "OWNER", "body": "I created https://github.com/simonw/datasette-plugin-demos which is now published to PyPI and can be installed with `pip install datasette-plugin-demos` - I've confirmed that if you DO install it my Datasette `plugins` branch picks up the plugins, and `select random_integer(1, 4)` works as it should.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-381450591", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 381450591, "node_id": "MDEyOklzc3VlQ29tbWVudDM4MTQ1MDU5MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-04-16T00:30:22Z", "updated_at": "2018-04-16T00:34:42Z", "author_association": "OWNER", "body": "Slight code design problem... when I tried installing my branch in a fresh virtual environment I got this error, because `setup.py` now depends on `pluggy` (from importing `__version__`):\r\n\r\n```\r\n File \"/private/var/folders/jj/fngnv0810tn2lt_kd3911pdc0000gp/T/pip-req-build-dftqdezt/setup.py\", line 2, in \r\n from datasette import __version__\r\n File \"/private/var/folders/jj/fngnv0810tn2lt_kd3911pdc0000gp/T/pip-req-build-dftqdezt/datasette/__init__.py\", line 2, in \r\n from .hookspecs import hookimpl # noqa\r\n File \"/private/var/folders/jj/fngnv0810tn2lt_kd3911pdc0000gp/T/pip-req-build-dftqdezt/datasette/hookspecs.py\", line 1, in \r\n from pluggy import HookimplMarker\r\n ModuleNotFoundError: No module named 'pluggy'\r\n```\r\n\r\nLooks like I've run into point 6 on https://packaging.python.org/guides/single-sourcing-package-version/ :\r\n\r\n![2018-04-15 at 5 34 pm](https://user-images.githubusercontent.com/9599/38785314-403ce86a-40d3-11e8-8542-ba426eddf4ac.png)\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-381611738", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 381611738, "node_id": "MDEyOklzc3VlQ29tbWVudDM4MTYxMTczOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-04-16T14:07:30Z", "updated_at": "2018-04-16T14:07:30Z", "author_association": "OWNER", "body": "I should check if it's possible to have two template registration function plugins in a single plugin module. If it isn't maybe I should use class plugins instead of module plugins.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-381621338", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 381621338, "node_id": "MDEyOklzc3VlQ29tbWVudDM4MTYyMTMzOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-04-16T14:36:27Z", "updated_at": "2018-04-16T14:36:27Z", "author_association": "OWNER", "body": "Annoyingly, the following only results in the last of the two `prepare_connection` hooks being registered:\r\n\r\n```\r\nfrom datasette import hookimpl\r\nimport pint\r\nimport random\r\n\r\nureg = pint.UnitRegistry()\r\n\r\n\r\n@hookimpl\r\ndef prepare_connection(conn):\r\n def convert_units(amount, from_, to_):\r\n \"select convert_units(100, 'm', 'ft');\"\r\n return (amount * ureg(from_)).to(to_).to_tuple()[0]\r\n conn.create_function('convert_units', 3, convert_units)\r\n\r\n\r\n@hookimpl\r\ndef prepare_connection(conn):\r\n conn.create_function('random_integer', 2, random.randint)\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-381622793", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 381622793, "node_id": "MDEyOklzc3VlQ29tbWVudDM4MTYyMjc5Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-04-16T14:40:39Z", "updated_at": "2018-04-17T01:47:15Z", "author_association": "OWNER", "body": "I think that's OK. The two plugins I've implemented so far (`prepare_connection` and `prepare_jinja2_environment`) both make sense if they can only be defined once-per-plugin. For the moment I'll assume I can define future hooks to work well with the same limitation.\r\n\r\nThe syntactic sugar idea in #220 can help here too.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-381809998", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 381809998, "node_id": "MDEyOklzc3VlQ29tbWVudDM4MTgwOTk5OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-04-17T02:23:39Z", "updated_at": "2018-04-17T02:23:39Z", "author_association": "OWNER", "body": "I just shipped Datasette 0.19 with where I'm at so far: https://github.com/simonw/datasette/releases/tag/0.19", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-382256729", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 382256729, "node_id": "MDEyOklzc3VlQ29tbWVudDM4MjI1NjcyOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-04-18T04:29:29Z", "updated_at": "2018-04-18T04:30:14Z", "author_association": "OWNER", "body": "I added a mechanism for plugins to serve static files and define custom CSS and JS URLs in #214 - see new documentation on http://datasette.readthedocs.io/en/latest/plugins.html#static-assets and http://datasette.readthedocs.io/en/latest/plugins.html#extra-css-urls", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-383139889", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 383139889, "node_id": "MDEyOklzc3VlQ29tbWVudDM4MzEzOTg4OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-04-20T15:51:47Z", "updated_at": "2018-04-20T15:51:47Z", "author_association": "OWNER", "body": "I released everything we have so far in [Datasette 0.20](https://github.com/simonw/datasette/releases/tag/0.20) and built and released an example plugin, [datasette-cluster-map](https://pypi.org/project/datasette-cluster-map/). Here's my blog entry about it: https://simonwillison.net/2018/Apr/20/datasette-plugins/", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-383140111", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 383140111, "node_id": "MDEyOklzc3VlQ29tbWVudDM4MzE0MDExMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-04-20T15:52:33Z", "updated_at": "2018-04-20T15:52:33Z", "author_association": "OWNER", "body": "Here's a link demonstrating my new plugin: https://datasette-cluster-map-demo.now.sh/polar-bears-455fe3a/USGS_WC_eartags_output_files_2009-2011-Status", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/14#issuecomment-491944613", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/14", "id": 491944613, "node_id": "MDEyOklzc3VlQ29tbWVudDQ5MTk0NDYxMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-05-13T18:58:19Z", "updated_at": "2019-05-13T18:58:19Z", "author_association": "OWNER", "body": "We've grown a bunch of plugin hooks over the past two years: https://datasette.readthedocs.io/en/latest/plugins.html#plugin-hooks\r\n\r\nSince the plugin system will never be 100% \"finished\", I'm closing this in favor of the label: https://github.com/simonw/datasette/labels/plugins", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267707940, "label": "Datasette Plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/16#issuecomment-338768860", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/16", "id": 338768860, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODc2ODg2MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T19:23:29Z", "updated_at": "2017-10-23T19:23:29Z", "author_association": "OWNER", "body": "I could use the table-reflow mechanism demonstrated here: http://demos.jquerymobile.com/1.4.3/table-reflow/", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267726219, "label": "Default HTML/CSS needs to look reasonable and be responsive"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/16#issuecomment-339420462", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/16", "id": 339420462, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTQyMDQ2Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-25T18:10:51Z", "updated_at": "2017-10-25T18:10:51Z", "author_association": "OWNER", "body": "https://sitesforprofit.com/responsive-table-plugins-and-patterns has some useful links.\r\n\r\nI really like the pattern from https://css-tricks.com/responsive-data-tables/\r\n\r\n /* \r\n Max width before this PARTICULAR table gets nasty\r\n This query will take effect for any screen smaller than 760px\r\n and also iPads specifically.\r\n */\r\n @media \r\n only screen and (max-width: 760px),\r\n (min-device-width: 768px) and (max-device-width: 1024px) {\r\n\r\n /* Force table to not be like tables anymore */\r\n table, thead, tbody, th, td, tr { \r\n display: block; \r\n }\r\n \r\n /* Hide table headers (but not display: none;, for accessibility) */\r\n thead tr { \r\n position: absolute;\r\n top: -9999px;\r\n left: -9999px;\r\n }\r\n \r\n tr { border: 1px solid #ccc; }\r\n \r\n td { \r\n /* Behave like a \"row\" */\r\n border: none;\r\n border-bottom: 1px solid #eee; \r\n position: relative;\r\n padding-left: 50%; \r\n }\r\n \r\n td:before { \r\n /* Now like a table header */\r\n position: absolute;\r\n /* Top/left values mimic padding */\r\n top: 6px;\r\n left: 6px;\r\n width: 45%; \r\n padding-right: 10px; \r\n white-space: nowrap;\r\n }\r\n \r\n /*\r\n Label the data\r\n */\r\n td:nth-of-type(1):before { content: \"First Name\"; }\r\n td:nth-of-type(2):before { content: \"Last Name\"; }\r\n td:nth-of-type(3):before { content: \"Job Title\"; }\r\n td:nth-of-type(4):before { content: \"Favorite Color\"; }\r\n td:nth-of-type(5):before { content: \"Wars of Trek?\"; }\r\n td:nth-of-type(6):before { content: \"Porn Name\"; }\r\n td:nth-of-type(7):before { content: \"Date of Birth\"; }\r\n td:nth-of-type(8):before { content: \"Dream Vacation City\"; }\r\n td:nth-of-type(9):before { content: \"GPA\"; }\r\n td:nth-of-type(10):before { content: \"Arbitrary Data\"; }\r\n }", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267726219, "label": "Default HTML/CSS needs to look reasonable and be responsive"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/16#issuecomment-342032943", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/16", "id": 342032943, "node_id": "MDEyOklzc3VlQ29tbWVudDM0MjAzMjk0Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-06T02:50:07Z", "updated_at": "2017-11-06T02:50:07Z", "author_association": "OWNER", "body": "Default look with Bootstrap 4 looks like this:\r\n\"flights\"\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267726219, "label": "Default HTML/CSS needs to look reasonable and be responsive"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/16#issuecomment-343643332", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/16", "id": 343643332, "node_id": "MDEyOklzc3VlQ29tbWVudDM0MzY0MzMzMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-11T06:00:04Z", "updated_at": "2017-11-11T06:00:04Z", "author_association": "OWNER", "body": "Here's what a table looks like now at a smaller screen size:\r\n\r\n\"parlgov-development__info_data_source\"\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267726219, "label": "Default HTML/CSS needs to look reasonable and be responsive"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/16#issuecomment-343647300", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/16", "id": 343647300, "node_id": "MDEyOklzc3VlQ29tbWVudDM0MzY0NzMwMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-11T07:41:19Z", "updated_at": "2017-11-11T07:53:09Z", "author_association": "OWNER", "body": "Still needed:\r\n\r\n- [ ] A link to the homepage from some kind of navigation bar in the header\r\n- [ ] link to github.com/simonw/datasette in the footer\r\n- [ ] Slightly better titles (maybe ditch the visited link colours for titles only? should keep those for primary key links)\r\n- [ ] Links to the .json and .jsono versions of every view", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267726219, "label": "Default HTML/CSS needs to look reasonable and be responsive"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/16#issuecomment-343691342", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/16", "id": 343691342, "node_id": "MDEyOklzc3VlQ29tbWVudDM0MzY5MTM0Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-11T20:19:07Z", "updated_at": "2017-11-11T20:19:07Z", "author_association": "OWNER", "body": "Closing this, opening a fresh ticket for the navigation stuff.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267726219, "label": "Default HTML/CSS needs to look reasonable and be responsive"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/17#issuecomment-338852971", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/17", "id": 338852971, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODg1Mjk3MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T02:26:47Z", "updated_at": "2017-10-24T02:26:47Z", "author_association": "OWNER", "body": "I'm not going to bother with this.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267732005, "label": "In development mode, should still pick up new .db files"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/18#issuecomment-754188383", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/18", "id": 754188383, "node_id": "MDEyOklzc3VlQ29tbWVudDc1NDE4ODM4Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-01-04T20:05:48Z", "updated_at": "2021-01-04T20:05:48Z", "author_association": "OWNER", "body": "I'm not using Sanic any more, but this is still very feasible. If I ever do it I'll write a plugin.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267739593, "label": "See if I can get a websockets interface working"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/19#issuecomment-339366612", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/19", "id": 339366612, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTM2NjYxMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-25T15:21:16Z", "updated_at": "2017-10-25T15:21:16Z", "author_association": "OWNER", "body": "I had to manually set the content disposition header:\r\n\r\n return await response.file_stream(\r\n filepath, headers={\r\n 'Content-Disposition': 'attachment; filename=\"{}\"'.format(ilepath)\r\n }\r\n )\r\n\r\nIn the next release of Sanic I can just use the filename= argument instead:\r\n\r\nhttps://github.com/channelcat/sanic/commit/07e95dba4f5983afc1e673df14bdd278817288aa", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267741262, "label": "Efficient url for downloading the raw database file"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/20#issuecomment-338769538", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/20", "id": 338769538, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODc2OTUzOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-23T19:25:55Z", "updated_at": "2017-10-23T19:25:55Z", "author_association": "OWNER", "body": "Maybe this should be handled by views instead?\r\n\r\nhttps://stateless-datasets-wreplxalgu.now.sh/ lists some views\r\n\r\nhttps://stateless-datasets-wreplxalgu.now.sh/?sql=select%20*%20from%20%22Order%20Subtotals%22 is an example showing the content of a view.\r\n\r\nWhat would the URL to views be? I don't think a view can share a name with a table, so the same URL scheme could work for both.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267759136, "label": "Config file with support for defining canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/20#issuecomment-343581130", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/20", "id": 343581130, "node_id": "MDEyOklzc3VlQ29tbWVudDM0MzU4MTEzMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-10T20:44:38Z", "updated_at": "2017-11-10T20:44:38Z", "author_association": "OWNER", "body": "I'm going to handle this a different way. I'm going to support a local history of your own queries stored in localStorage, but if you want to share a query you have to do it with a URL.\r\n\r\nIf people really want canned query support, they can do that using custom templates - see #12 - or by adding views to their database before they publish it.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267759136, "label": "Config file with support for defining canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/20#issuecomment-348420129", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/20", "id": 348420129, "node_id": "MDEyOklzc3VlQ29tbWVudDM0ODQyMDEyOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-12-01T07:16:25Z", "updated_at": "2017-12-01T07:16:25Z", "author_association": "OWNER", "body": "I've found some examples of canned queries I want to support that can't be represented as views, so I'm going to reopen this.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267759136, "label": "Config file with support for defining canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/20#issuecomment-348420955", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/20", "id": 348420955, "node_id": "MDEyOklzc3VlQ29tbWVudDM0ODQyMDk1NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-12-01T07:21:08Z", "updated_at": "2017-12-01T07:21:08Z", "author_association": "OWNER", "body": "I'll use the existing metadata.json file:\r\n\r\n {\r\n \"databases\": {\r\n \"mydb\": {\r\n \"queries\": {\r\n \"custom_thingy\": {...\r\n\r\nThe query definition can either be just a string of SQL, or it can be an object with a sql key and optional title and description keys.\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267759136, "label": "Config file with support for defining canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/20#issuecomment-348860623", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/20", "id": 348860623, "node_id": "MDEyOklzc3VlQ29tbWVudDM0ODg2MDYyMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-12-04T04:56:21Z", "updated_at": "2017-12-04T04:56:21Z", "author_association": "OWNER", "body": "While I'm doing this, I could add per-database and per-table metadata too ala #68", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267759136, "label": "Config file with support for defining canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/20#issuecomment-349027974", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/20", "id": 349027974, "node_id": "MDEyOklzc3VlQ29tbWVudDM0OTAyNzk3NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-12-04T17:01:19Z", "updated_at": "2017-12-04T17:01:19Z", "author_association": "OWNER", "body": " This is also a good opportunity to re-factor out a separate query.html template - right now the database.html template is doing two jobs.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267759136, "label": "Config file with support for defining canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/20#issuecomment-349359498", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/20", "id": 349359498, "node_id": "MDEyOklzc3VlQ29tbWVudDM0OTM1OTQ5OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-12-05T16:30:06Z", "updated_at": "2017-12-05T16:30:06Z", "author_association": "OWNER", "body": "Named canned queries can now be defined in metadata.json like this:\r\n \r\n {\r\n \"databases\": {\r\n \"timezones\": {\r\n \"queries\": {\r\n \"timezone_for_point\": \"select tzid from timezones ...\"\r\n }\r\n }\r\n }\r\n }\r\n \r\nThese will be shown in a new \"Queries\" section beneath \"Views\" on the database page.\r\n\r\n\"timezones\"\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": 267759136, "label": "Config file with support for defining canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/20#issuecomment-349383276", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/20", "id": 349383276, "node_id": "MDEyOklzc3VlQ29tbWVudDM0OTM4MzI3Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-12-05T17:45:20Z", "updated_at": "2017-12-05T17:45:20Z", "author_association": "OWNER", "body": "http://datasette.readthedocs.io/en/latest/sql_queries.html", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267759136, "label": "Config file with support for defining canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/20#issuecomment-349406761", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/20", "id": 349406761, "node_id": "MDEyOklzc3VlQ29tbWVudDM0OTQwNjc2MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-12-05T19:03:06Z", "updated_at": "2017-12-05T19:03:06Z", "author_association": "OWNER", "body": "Demo: https://timezones-api.now.sh/timezones-3cb9f64/by_point", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267759136, "label": "Config file with support for defining canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/21#issuecomment-343581332", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/21", "id": 343581332, "node_id": "MDEyOklzc3VlQ29tbWVudDM0MzU4MTMzMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-10T20:45:42Z", "updated_at": "2017-11-10T20:45:42Z", "author_association": "OWNER", "body": "I'm not going to use Sanic's mechanism for this. I'll use arguments passed to my cli instead.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267769034, "label": "Use Sanic configuration mechanism "}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/23#issuecomment-338854988", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/23", "id": 338854988, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODg1NDk4OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T02:40:12Z", "updated_at": "2017-10-25T00:05:46Z", "author_association": "OWNER", "body": " /database-name/table-name?name__contains=simon&sort=id+desc\r\n\r\nNote that if there's a column called \"sort\" you can still do sort__exact=blah\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": 267788884, "label": "Support Django-style filters in querystring arguments"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/23#issuecomment-338859620", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/23", "id": 338859620, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODg1OTYyMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T03:11:42Z", "updated_at": "2017-10-24T03:11:42Z", "author_association": "OWNER", "body": "I\u2019m going to implement everything in https://docs.djangoproject.com/en/1.11/ref/models/querysets/#field-lookups with the exception of range and the various date ones.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267788884, "label": "Support Django-style filters in querystring arguments"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/23#issuecomment-338859709", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/23", "id": 338859709, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODg1OTcwOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T03:12:18Z", "updated_at": "2017-10-24T03:12:42Z", "author_association": "OWNER", "body": "I\u2019m going to need to write unit tests for this, is this depends on #9", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267788884, "label": "Support Django-style filters in querystring arguments"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/23#issuecomment-339138809", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/23", "id": 339138809, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTEzODgwOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T21:32:46Z", "updated_at": "2017-10-24T21:32:46Z", "author_association": "OWNER", "body": "May as well support most of https://sqlite.org/lang_expr.html", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267788884, "label": "Support Django-style filters in querystring arguments"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/23#issuecomment-339186887", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/23", "id": 339186887, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTE4Njg4Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-25T01:39:43Z", "updated_at": "2017-10-25T04:22:41Z", "author_association": "OWNER", "body": "Still to do:\r\n\r\n- [x] `gt`, `gte`, `lt`, `lte`\r\n- [x] `like`\r\n- [x] `glob`\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267788884, "label": "Support Django-style filters in querystring arguments"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/23#issuecomment-339210353", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/23", "id": 339210353, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTIxMDM1Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-25T04:23:02Z", "updated_at": "2017-10-25T04:23:02Z", "author_association": "OWNER", "body": "I'm going to call this one done for the moment. The date filters can go in a stretch goal.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267788884, "label": "Support Django-style filters in querystring arguments"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/24#issuecomment-338834213", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/24", "id": 338834213, "node_id": "MDEyOklzc3VlQ29tbWVudDMzODgzNDIxMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T00:23:05Z", "updated_at": "2017-10-24T00:23:05Z", "author_association": "OWNER", "body": "If I can\u2019t setect a primary key, I won\u2019t provide a URL for those records", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267828746, "label": "Implement full URL design"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/24#issuecomment-339003850", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/24", "id": 339003850, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTAwMzg1MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T14:12:00Z", "updated_at": "2017-10-24T14:12:00Z", "author_association": "OWNER", "body": "As of b46e370ee6126aa2fa85cf789a31da38aed98496 this is done.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267828746, "label": "Implement full URL design"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/25#issuecomment-343715915", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/25", "id": 343715915, "node_id": "MDEyOklzc3VlQ29tbWVudDM0MzcxNTkxNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-12T06:08:28Z", "updated_at": "2017-11-12T06:08:28Z", "author_association": "OWNER", "body": " con = sqlite3.connect('existing_db.db')\r\n with open('dump.sql', 'w') as f:\r\n for line in con.iterdump():\r\n f.write('%s\\n' % line)\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267857622, "label": "Endpoint that returns SQL ready to be piped into DB"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/25#issuecomment-344487639", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/25", "id": 344487639, "node_id": "MDEyOklzc3VlQ29tbWVudDM0NDQ4NzYzOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-15T05:11:11Z", "updated_at": "2017-11-15T05:11:11Z", "author_association": "OWNER", "body": "Since you can already download the database directly, I'm not going to bother with this one.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267857622, "label": "Endpoint that returns SQL ready to be piped into DB"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/26#issuecomment-343644976", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/26", "id": 343644976, "node_id": "MDEyOklzc3VlQ29tbWVudDM0MzY0NDk3Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-11T06:42:23Z", "updated_at": "2017-11-11T06:42:23Z", "author_association": "OWNER", "body": "Simplest version of this:\r\n\r\n1. Create a temporary directory\r\n2. Write a Dockerfile into it that pulls an image and pip installs datasette\r\n3. Add symlinks to the DBs they listed (so we don't have to copy them)\r\n4. Shell out to \"now\"\r\n5. Done!\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267861210, "label": "Command line tool for uploading one or more DBs to Now"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/26#issuecomment-343645249", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/26", "id": 343645249, "node_id": "MDEyOklzc3VlQ29tbWVudDM0MzY0NTI0OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-11T06:48:59Z", "updated_at": "2017-11-11T06:48:59Z", "author_association": "OWNER", "body": "Doing this works:\r\n\r\n import os\r\n os.link('/tmp/databases/northwind.db', '/tmp/tmp-blah/northwind.db')\r\n\r\nThat creates a link in tmp-blah - and then when I delete that entire directory like so:\r\n\r\n import shutil\r\n shutil.rmtree('/tmp/tmp-blah')\r\n\r\nThe original database is not deleted, just the link.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267861210, "label": "Command line tool for uploading one or more DBs to Now"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/26#issuecomment-343645327", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/26", "id": 343645327, "node_id": "MDEyOklzc3VlQ29tbWVudDM0MzY0NTMyNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-11T06:51:16Z", "updated_at": "2017-11-11T06:51:16Z", "author_association": "OWNER", "body": "I can create the temporary directory like so:\r\n\r\n import tempfile\r\n t = tempfile.TemporaryDirectory()\r\n t\r\n \r\n t.name\r\n '/var/folders/w9/0xm39tk94ng9h52g06z4b54c0000gp/T/tmpkym70wlp'\r\n\r\nAnd then to delete it all:\r\n\r\n t.cleanup()\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267861210, "label": "Command line tool for uploading one or more DBs to Now"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/27#issuecomment-344179878", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/27", "id": 344179878, "node_id": "MDEyOklzc3VlQ29tbWVudDM0NDE3OTg3OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-14T08:21:22Z", "updated_at": "2017-11-14T08:21:22Z", "author_association": "OWNER", "body": "https://github.com/frappe/charts perhaps ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267886330, "label": "Ability to plot a simple graph"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/27#issuecomment-345652450", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/27", "id": 345652450, "node_id": "MDEyOklzc3VlQ29tbWVudDM0NTY1MjQ1MA==", "user": {"value": 198537, "label": "rgieseke"}, "created_at": "2017-11-20T10:19:39Z", "updated_at": "2017-11-20T10:19:39Z", "author_association": "CONTRIBUTOR", "body": "If Data Package metadata gets adopted (#105) the views spec work might also be worth a look:\r\n\r\nhttp://frictionlessdata.io/specs/views/\r\n\r\nhttp://datahub.io/docs/features/views\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267886330, "label": "Ability to plot a simple graph"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/27#issuecomment-403910774", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/27", "id": 403910774, "node_id": "MDEyOklzc3VlQ29tbWVudDQwMzkxMDc3NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-07-10T17:52:41Z", "updated_at": "2018-07-10T17:52:41Z", "author_association": "OWNER", "body": "I consider this handled by https://github.com/simonw/datasette-vega", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 267886330, "label": "Ability to plot a simple graph"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/29#issuecomment-339019873", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/29", "id": 339019873, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTAxOTg3Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-24T14:58:33Z", "updated_at": "2017-10-24T14:58:33Z", "author_association": "OWNER", "body": "Here's what I've got now:\r\n\r\n\"localhost_8006_northwind-40d049b_categories_json\"\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268050821, "label": "Handle bytestring records encoding to JSON"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/30#issuecomment-344352573", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/30", "id": 344352573, "node_id": "MDEyOklzc3VlQ29tbWVudDM0NDM1MjU3Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-14T18:29:01Z", "updated_at": "2017-11-14T18:29:01Z", "author_association": "OWNER", "body": "This is a dupe of #85 ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268078453, "label": "Do something neat with foreign keys"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/31#issuecomment-392580715", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/31", "id": 392580715, "node_id": "MDEyOklzc3VlQ29tbWVudDM5MjU4MDcxNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-05-28T18:10:45Z", "updated_at": "2018-05-28T18:10:45Z", "author_association": "OWNER", "body": "Oops, that commit should have referenced #121 ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268087542, "label": "Idea: colour scheme based on sha256 of db"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/32#issuecomment-343164111", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/32", "id": 343164111, "node_id": "MDEyOklzc3VlQ29tbWVudDM0MzE2NDExMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-09T14:05:56Z", "updated_at": "2017-11-09T14:05:56Z", "author_association": "OWNER", "body": "Implemented in 31b21f5c5e15fc3acab7fabb170c1da71dc3c98c", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268106803, "label": "Try running SQLite queries in a separate thread"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/34#issuecomment-392600866", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/34", "id": 392600866, "node_id": "MDEyOklzc3VlQ29tbWVudDM5MjYwMDg2Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-05-28T20:45:34Z", "updated_at": "2018-05-28T20:45:42Z", "author_association": "OWNER", "body": "This is an accidental duplicate, work is now taking place in #266", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268176505, "label": "Support CSV export with a .csv extension"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/36#issuecomment-345262738", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/36", "id": 345262738, "node_id": "MDEyOklzc3VlQ29tbWVudDM0NTI2MjczOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-17T14:45:37Z", "updated_at": "2017-11-17T14:45:37Z", "author_association": "OWNER", "body": "Consider for example https://fivethirtyeight.datasettes.com/fivethirtyeight/inconvenient-sequel%2Fratings\r\n\r\n\"fivethirtyeight__inconvenient-sequel_ratings\"\r\n\r\nThe idea here is to be able to support querystring parameters like this:\r\n\r\n* `?timestamp___date=2017-07-17` - return every item where the timestamp falls on that date\r\n* `?timestamp___year=2017` - return every item where the timestamp falls within 2017\r\n* `?timestamp___month=1` - return every item where the month component is January\r\n* `?timestamp___day=10` - return every item where the day-of-the-month component is 10\r\n\r\nThis is similar to #64 but a fair bit more complicated. \r\n\r\nSQLite date functions are documented here: https://sqlite.org/lang_datefunc.html\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268262480, "label": "date, year, month and day querystring lookups"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/36#issuecomment-345448756", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/36", "id": 345448756, "node_id": "MDEyOklzc3VlQ29tbWVudDM0NTQ0ODc1Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-11-18T15:17:43Z", "updated_at": "2017-11-18T15:17:43Z", "author_association": "OWNER", "body": "This may be useful:\r\n\r\nhttps://github.com/coleifer/peewee/blob/db85167d93861451a1fe7cde8c4f05748b222634/peewee.py#L162-L185", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268262480, "label": "date, year, month and day querystring lookups"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/36#issuecomment-392575160", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/36", "id": 392575160, "node_id": "MDEyOklzc3VlQ29tbWVudDM5MjU3NTE2MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-05-28T17:30:52Z", "updated_at": "2018-05-28T17:30:52Z", "author_association": "OWNER", "body": "I've changed my mind about this.\r\n\r\n\"Select every record on the 3rd day of the month\" doesn't strike me as an actually useful feature.\r\n\r\n\"Select every record in 2018 / in May 2018 / on 1st May 2018\", if you are using the SQLite-preferred datestring format, are already supported using LIKE queries (or the startswith filter):\r\n\r\n* https://fivethirtyeight.datasettes.com/fivethirtyeight/inconvenient-sequel%2Fratings?timestamp__startswith=2017\r\n* https://fivethirtyeight.datasettes.com/fivethirtyeight/inconvenient-sequel%2Fratings?timestamp__startswith=2017-08\r\n* https://fivethirtyeight.datasettes.com/fivethirtyeight/inconvenient-sequel%2Fratings?timestamp__startswith=2017-08-29\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": 268262480, "label": "date, year, month and day querystring lookups"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/37#issuecomment-339382054", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/37", "id": 339382054, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTM4MjA1NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-25T16:05:56Z", "updated_at": "2017-10-25T16:05:56Z", "author_association": "OWNER", "body": "Could this be as simple as using the iterative JSON encoder and adding a yield statement in between each chunk?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268453968, "label": "Ability to serialize massive JSON without blocking event loop"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/37#issuecomment-636360861", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/37", "id": 636360861, "node_id": "MDEyOklzc3VlQ29tbWVudDYzNjM2MDg2MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-05-30T17:29:20Z", "updated_at": "2020-05-30T17:29:20Z", "author_association": "OWNER", "body": "I'm not going to do this: 2.5 years later I have yet to run into anything that makes me think that JSON serialization performance is worth any extra work.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268453968, "label": "Ability to serialize massive JSON without blocking event loop"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/38#issuecomment-339388215", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/38", "id": 339388215, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTM4ODIxNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-25T16:25:45Z", "updated_at": "2017-10-25T16:25:45Z", "author_association": "OWNER", "body": "First experiment: hook up an iterative CSV dump (just because that\u2019s a tiny bit easier to get started with than iterative a JSON). Have it execute a big select statement and then iterate through the result set 100 rows at a time using sqite fetchmany() - also have it async sleep for a second in between each batch of 100.\r\n\r\nCan this work without needing python threads? ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268462768, "label": "Experiment with patterns for concurrent long running queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/38#issuecomment-339388771", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/38", "id": 339388771, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTM4ODc3MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-25T16:27:29Z", "updated_at": "2017-10-25T16:27:29Z", "author_association": "OWNER", "body": "If this does work, I need to figure it what to do about the HTML view. ASsuming I can iteratively produce JSON and CSV, what to do about HTML? One option: render the first 500 rows as HTML, then hand off to an infinite scroll experience that iteratively loads more rows as JSON.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268462768, "label": "Experiment with patterns for concurrent long running queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/38#issuecomment-339389105", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/38", "id": 339389105, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTM4OTEwNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-25T16:28:39Z", "updated_at": "2017-10-25T16:28:39Z", "author_association": "OWNER", "body": "The gold standard here is to be able to serve up increasingly large datasets without blocking the event loop and while using a sustainable amount of RAM", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268462768, "label": "Experiment with patterns for concurrent long running queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/38#issuecomment-339389328", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/38", "id": 339389328, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTM4OTMyOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-25T16:29:23Z", "updated_at": "2017-10-25T16:29:23Z", "author_association": "OWNER", "body": "Ideally we can get some serious gains from the fact that our database file is opened with the immutable option.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268462768, "label": "Experiment with patterns for concurrent long running queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/38#issuecomment-392601114", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/38", "id": 392601114, "node_id": "MDEyOklzc3VlQ29tbWVudDM5MjYwMTExNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-05-28T20:47:31Z", "updated_at": "2018-05-28T20:47:31Z", "author_association": "OWNER", "body": "I think the way Datasette executes SQL queries in a thread pool introduced in #45 is a good solution for this ticket.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268462768, "label": "Experiment with patterns for concurrent long running queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/39#issuecomment-339406634", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/39", "id": 339406634, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTQwNjYzNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-25T17:27:10Z", "updated_at": "2017-10-25T17:27:10Z", "author_association": "OWNER", "body": "It certainly looks like some of the stuff in https://sqlite.org/pragma.html could be used to screw around with things. Example: `PRAGMA case_sensitive_like = 1` - would that affect future queries?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268469569, "label": "Protect against malicious SQL that causes damage even though our DB is immutable"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/39#issuecomment-339413825", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/39", "id": 339413825, "node_id": "MDEyOklzc3VlQ29tbWVudDMzOTQxMzgyNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2017-10-25T17:48:48Z", "updated_at": "2017-10-25T17:48:48Z", "author_association": "OWNER", "body": "Could I use https://sqlparse.readthedocs.io/en/latest/ to parse incoming statements and ensure they are pure SELECTs? Would that prevent people from using a compound SELECT statement to trigger an evil PRAGMA of some sort?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 268469569, "label": "Protect against malicious SQL that causes damage even though our DB is immutable"}, "performed_via_github_app": null}