(impact)`, `\u00f8 = not affected`, `? = missing data`\n> Powered by [Codecov](https://codecov.io/gh/simonw/datasette/pull/1296?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Last update [c73af5d...8f00c31](https://codecov.io/gh/simonw/datasette/pull/1296?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 855446829, "label": "Dockerfile: use Ubuntu 20.10 as base"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1295#issuecomment-817301355", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1295", "id": 817301355, "node_id": "MDEyOklzc3VlQ29tbWVudDgxNzMwMTM1NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-11T12:40:25Z", "updated_at": "2021-04-11T12:41:06Z", "author_association": "OWNER", "body": "I could have a page about error codes in the docs, then have `https://datasette.io/E123` style URLs for each error core which are shown when that error occurs and redirect to the corresponding documentation section.\r\n\r\nCan enforce these with a documentation unit test.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 855296937, "label": "Errors should have links to further information"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1286#issuecomment-815978405", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1286", "id": 815978405, "node_id": "MDEyOklzc3VlQ29tbWVudDgxNTk3ODQwNQ==", "user": {"value": 192568, "label": "mroswell"}, "created_at": "2021-04-08T16:47:29Z", "updated_at": "2021-04-10T03:59:00Z", "author_association": "CONTRIBUTOR", "body": "This worked for me: \r\n`{{ cell.value | replace('\", \"','; ') | replace('[\\\"','') | replace('\\\"]','')}} | `\r\n\r\nI'm sure there is a prettier (and more flexible) way, but for now, this is ever-so-much more pleasant to look at. \r\n\r\n------ AFTER:\r\n\r\n\r\n------ BEFORE:\r\n\r\n\r\n\r\n\r\n(Note: I didn't figure out how to have one item have no semicolon, while multi-items close with a semicolon, but this is good enough for now. I also didn't figure out how to set up a new jinja filter. I don't want to add to /datasette/utils/__init__.py as I assume that would get overwritten when upgrading datasette. Having a starter guide on creating jinja filters in datasette would be helpful. (The jinja documentation isn't datasette-specific enough for me to quite nail it.)\r\n", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849220154, "label": "Better default display of arrays of items"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813438771", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813438771, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzQzODc3MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-05T14:58:48Z", "updated_at": "2021-04-05T14:58:48Z", "author_association": "OWNER", "body": "I may need to do something special for rowid columns - there is a `RowId` opcode that might come into play here.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813480043", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813480043, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzQ4MDA0Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-05T16:16:17Z", "updated_at": "2021-04-05T16:16:17Z", "author_association": "OWNER", "body": "https://latest.datasette.io/fixtures?sql=explain+select+*+from+paginated_view will be an interesting test query - because `paginated_view` is defined like this:\r\n\r\n```sql\r\nCREATE VIEW paginated_view AS\r\n SELECT\r\n content,\r\n '- ' || content || ' -' AS content_extra\r\n FROM no_primary_key;\r\n```\r\nSo this will help test that the mechanism isn't confused by output columns that are created through a concatenation expression.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813445512", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813445512, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzQ0NTUxMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-05T15:11:40Z", "updated_at": "2021-04-05T15:11:40Z", "author_association": "OWNER", "body": "Here's some older example code that works with opcodes from Python, in this case to output indexes used by a query: https://github.com/plasticityai/supersqlite/blob/master/supersqlite/idxchk.py", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/dogsheep/dogsheep-photos/issues/35#issuecomment-813249000", "issue_url": "https://api.github.com/repos/dogsheep/dogsheep-photos/issues/35", "id": 813249000, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzI0OTAwMA==", "user": {"value": 1151557, "label": "ligurio"}, "created_at": "2021-04-05T07:37:57Z", "updated_at": "2021-04-05T07:37:57Z", "author_association": "NONE", "body": "There are trained ML models used in Photoprism:\r\n- https://dl.photoprism.org/tensorflow/nasnet.zip\r\n- https://dl.photoprism.org/tensorflow/nsfw.zip", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 842695374, "label": "Support to annotate photos on other than macOS OSes"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813134637", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813134637, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzEzNDYzNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-05T01:21:59Z", "updated_at": "2021-04-05T01:21:59Z", "author_association": "OWNER", "body": "http://www.sqlite.org/draft/lang_explain.html says:\r\n\r\n> Applications should not use EXPLAIN or EXPLAIN QUERY PLAN since their exact behavior is variable and only partially documented.\r\n\r\nI'm going to keep exploring this though.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813134386", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813134386, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzEzNDM4Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-05T01:20:28Z", "updated_at": "2021-08-13T00:42:30Z", "author_association": "OWNER", "body": "... that output might also provide a better way to extract variables than the current mechanism using a regular expression, by looking for the `Variable` opcodes.\r\n\r\n[UPDATE: it did indeed do that, see #1421]", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813134227", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813134227, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzEzNDIyNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-05T01:19:31Z", "updated_at": "2021-04-05T01:19:31Z", "author_association": "OWNER", "body": "| addr | opcode | p1 | p2 | p3 | p4 | p5 | comment |\r\n|--------|---------------|------|------|------|-----------------------|------|-----------|\r\n| 0 | Init | 0 | 47 | 0 | | 00 | |\r\n| 1 | OpenRead | 0 | 51 | 0 | 15 | 00 | |\r\n| 2 | Integer | 15 | 2 | 0 | | 00 | |\r\n| 3 | Once | 0 | 15 | 0 | | 00 | |\r\n| 4 | OpenEphemeral | 2 | 1 | 0 | k(1,) | 00 | |\r\n| 5 | VOpen | 1 | 0 | 0 | vtab:3E692C362158 | 00 | |\r\n| 6 | String8 | 0 | 5 | 0 | CPAD_2020a_SuperUnits | 00 | |\r\n| 7 | SCopy | 7 | 6 | 0 | | 00 | |\r\n| 8 | Integer | 2 | 3 | 0 | | 00 | |\r\n| 9 | Integer | 2 | 4 | 0 | | 00 | |\r\n| 10 | VFilter | 1 | 15 | 3 | | 00 | |\r\n| 11 | Rowid | 1 | 8 | 0 | | 00 | |\r\n| 12 | MakeRecord | 8 | 1 | 9 | C | 00 | |\r\n| 13 | IdxInsert | 2 | 9 | 8 | 1 | 00 | |\r\n| 14 | VNext | 1 | 11 | 0 | | 00 | |\r\n| 15 | Return | 2 | 0 | 0 | | 00 | |\r\n| 16 | Rewind | 2 | 46 | 0 | | 00 | |\r\n| 17 | Column | 2 | 0 | 1 | | 00 | |\r\n| 18 | IsNull | 1 | 45 | 0 | | 00 | |\r\n| 19 | SeekRowid | 0 | 45 | 1 | | 00 | |\r\n| 20 | Column | 0 | 2 | 11 | | 00 | |\r\n| 21 | Function0 | 1 | 10 | 9 | like(2) | 02 | |\r\n| 22 | IfNot | 9 | 45 | 1 | | 00 | |\r\n| 23 | Column | 0 | 14 | 13 | | 00 | |\r\n| 24 | Function0 | 1 | 12 | 9 | intersects(2) | 02 | |\r\n| 25 | Ne | 14 | 45 | 9 | | 51 | |\r\n| 26 | Column | 0 | 14 | 9 | | 00 | |\r\n| 27 | Function0 | 0 | 9 | 15 | asgeojson(1) | 01 | |\r\n| 28 | Rowid | 0 | 16 | 0 | | 00 | |\r\n| 29 | Column | 0 | 1 | 17 | | 00 | |\r\n| 30 | Column | 0 | 2 | 18 | | 00 | |\r\n| 31 | Column | 0 | 3 | 19 | | 00 | |\r\n| 32 | Column | 0 | 4 | 20 | | 00 | |\r\n| 33 | Column | 0 | 5 | 21 | | 00 | |\r\n| 34 | Column | 0 | 6 | 22 | | 00 | |\r\n| 35 | Column | 0 | 7 | 23 | | 00 | |\r\n| 36 | Column | 0 | 8 | 24 | | 00 | |\r\n| 37 | Column | 0 | 9 | 25 | | 00 | |\r\n| 38 | Column | 0 | 10 | 26 | | 00 | |\r\n| 39 | Column | 0 | 11 | 27 | | 00 | |\r\n| 40 | RealAffinity | 27 | 0 | 0 | | 00 | |\r\n| 41 | Column | 0 | 12 | 28 | | 00 | |\r\n| 42 | Column | 0 | 13 | 29 | | 00 | |\r\n| 43 | Column | 0 | 14 | 30 | | 00 | |\r\n| 44 | ResultRow | 15 | 16 | 0 | | 00 | |\r\n| 45 | Next | 2 | 17 | 0 | | 00 | |\r\n| 46 | Halt | 0 | 0 | 0 | | 00 | |\r\n| 47 | Transaction | 0 | 0 | 265 | 0 | 01 | |\r\n| 48 | Variable | 1 | 31 | 0 | :freedraw | 00 | |\r\n| 49 | Function0 | 1 | 31 | 7 | geomfromgeojson(1) | 01 | |\r\n| 50 | String8 | 0 | 10 | 0 | %mini% | 00 | |\r\n| 51 | Variable | 1 | 32 | 0 | :freedraw | 00 | |\r\n| 52 | Function0 | 1 | 32 | 12 | geomfromgeojson(1) | 01 | |\r\n| 53 | Integer | 1 | 14 | 0 | | 00 | |\r\n| 54 | Goto | 0 | 1 | 0 | | 00 | |\r\n\r\nEssential documentation for understanding that output: https://www.sqlite.org/opcode.html", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813134072", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813134072, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzEzNDA3Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-05T01:18:37Z", "updated_at": "2021-04-05T01:18:37Z", "author_association": "OWNER", "body": "Had a fantastic suggestion on the SQLite forum: it might be possible to get what I want by interpreting the opcodes output by `explain select ...`.\r\n\r\nCopying the reply I posted to this thread:\r\n\r\nThat's really useful, thanks! It looks like it _might_ be possible for me to reconstruct where each column came from using the `explain select` output.\r\n\r\nHere's a complex example: \r\n\r\nIt looks like the opcodes I need to inspect are `OpenRead`, `Column` and `ResultRow`.\r\n\r\n`OpenRead` tells me which tables are being opened - the `p2` value (in this case 51) corresponds to the `rootpage` column in `sqlite_master` here: - it gets assigned to the register in `p1`.\r\n\r\nThe `Column` opcodes tell me which columns are being read - `p1` is that table reference, and `p2` is the `cid` of the column within that table.\r\n\r\nThe `ResultRow` opcode then tells me which columns are used in the results. `15 16` means start at the 15th and then read the next 16 columns.\r\n\r\nI think this might work!", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813116177", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813116177, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzExNjE3Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-04T23:31:00Z", "updated_at": "2021-04-04T23:31:00Z", "author_association": "OWNER", "body": "Sadly it doesn't do what I need. This query should only return one column, but instead I get back every column that was consulted by the query:\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": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813115607", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813115607, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzExNTYwNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-04T23:25:15Z", "updated_at": "2021-04-04T23:25:15Z", "author_association": "OWNER", "body": "Oh wow, I just spotted https://github.com/macbre/sql-metadata\r\n\r\n> Uses tokenized query returned by python-sqlparse and generates query metadata. Extracts column names and tables used by the query. Provides a helper for normalization of SQL queries and tables aliases resolving.\r\n\r\nIt's for MySQL, PostgreSQL and Hive right now but maybe getting it working with SQLite wouldn't be too hard?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813115414", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813115414, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzExNTQxNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-04T23:23:34Z", "updated_at": "2021-04-04T23:23:34Z", "author_association": "OWNER", "body": "The other approach I considered for this was to have my own SQL query parser running in Python, which could pick apart a complex query and figure out which column was sourced from which table. I dropped this idea because it felt that the moment `select *` came into play a pure parsing approach wouldn't work - I'd need knowledge of the schema in order to resolve the `*`.\r\n\r\nA Python parser approach might be good enough to handle a subset of queries - those that don't use `select *` for example - and maybe that would be worth shipping? The feature doesn't have to be perfect for it to be useful.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813114933", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813114933, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzExNDkzMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-04T23:19:22Z", "updated_at": "2021-04-04T23:19:22Z", "author_association": "OWNER", "body": "I asked about this on the SQLite forum: https://sqlite.org/forum/forumpost/0180277fb7", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813113653", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813113653, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzExMzY1Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-04T23:10:49Z", "updated_at": "2021-04-04T23:10:49Z", "author_association": "OWNER", "body": "One option I've not fully explored yet: could I write my own custom SQLite C extension which exposes this functionality as a callable function?\r\n\r\nThen I could load that extension and run a SQL query something like this:\r\n\r\n```\r\nselect database, table, column from analyze_query(:sql_query)\r\n```\r\nWhere `analyze_query(...)` would be a fancy virtual table function of some sort that uses the underlying `sqlite3_column_database_name()` C functions to analyze the SQL query and return details of what it would return.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813113403", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813113403, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzExMzQwMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-04T23:08:48Z", "updated_at": "2021-04-04T23:08:48Z", "author_association": "OWNER", "body": "Worth noting that adding `limit 0` to the query still causes it to conduct the permission checks, hopefully while avoiding doing any of the actual work of executing the query:\r\n```pycon\r\nIn [20]: db.execute('select * from compound_primary_key join facetable on facetable.rowid = compound_primary_key.rowid limit 0').fetchall()\r\n ...: \r\nargs (21, None, None, None, None) kwargs {}\r\nargs (20, 'compound_primary_key', 'pk1', 'main', None) kwargs {}\r\nargs (20, 'compound_primary_key', 'pk2', 'main', None) kwargs {}\r\nargs (20, 'compound_primary_key', 'content', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'pk', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'created', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'planet_int', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'on_earth', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'state', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'city_id', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'neighborhood', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'tags', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'complex_array', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'distinct_some_null', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'pk', 'main', None) kwargs {}\r\nargs (20, 'compound_primary_key', 'ROWID', 'main', None) kwargs {}\r\nOut[20]: []\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813113218", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813113218, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzExMzIxOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-04T23:07:25Z", "updated_at": "2021-04-04T23:07:25Z", "author_association": "OWNER", "body": "Here are all of the available constants:\r\n```pycon\r\nIn [3]: for k in dir(sqlite3):\r\n ...: if k.startswith(\"SQLITE_\"):\r\n ...: print(k, getattr(sqlite3, k))\r\n ...: \r\nSQLITE_ALTER_TABLE 26\r\nSQLITE_ANALYZE 28\r\nSQLITE_ATTACH 24\r\nSQLITE_CREATE_INDEX 1\r\nSQLITE_CREATE_TABLE 2\r\nSQLITE_CREATE_TEMP_INDEX 3\r\nSQLITE_CREATE_TEMP_TABLE 4\r\nSQLITE_CREATE_TEMP_TRIGGER 5\r\nSQLITE_CREATE_TEMP_VIEW 6\r\nSQLITE_CREATE_TRIGGER 7\r\nSQLITE_CREATE_VIEW 8\r\nSQLITE_CREATE_VTABLE 29\r\nSQLITE_DELETE 9\r\nSQLITE_DENY 1\r\nSQLITE_DETACH 25\r\nSQLITE_DONE 101\r\nSQLITE_DROP_INDEX 10\r\nSQLITE_DROP_TABLE 11\r\nSQLITE_DROP_TEMP_INDEX 12\r\nSQLITE_DROP_TEMP_TABLE 13\r\nSQLITE_DROP_TEMP_TRIGGER 14\r\nSQLITE_DROP_TEMP_VIEW 15\r\nSQLITE_DROP_TRIGGER 16\r\nSQLITE_DROP_VIEW 17\r\nSQLITE_DROP_VTABLE 30\r\nSQLITE_FUNCTION 31\r\nSQLITE_IGNORE 2\r\nSQLITE_INSERT 18\r\nSQLITE_OK 0\r\nSQLITE_PRAGMA 19\r\nSQLITE_READ 20\r\nSQLITE_RECURSIVE 33\r\nSQLITE_REINDEX 27\r\nSQLITE_SAVEPOINT 32\r\nSQLITE_SELECT 21\r\nSQLITE_TRANSACTION 22\r\nSQLITE_UPDATE 23\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813113175", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813113175, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzExMzE3NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-04T23:07:01Z", "updated_at": "2021-04-04T23:07:01Z", "author_association": "OWNER", "body": "A more promising route I found involved the `db.set_authorizer` method. This can be used to log the permission checks that SQLite uses, including checks for permission to access specific columns of specific tables. For a while I thought this could work!\r\n\r\n```pycon\r\n>>> def print_args(*args, **kwargs):\r\n... print(\"args\", args, \"kwargs\", kwargs)\r\n... return sqlite3.SQLITE_OK\r\n\r\n>>> db = sqlite3.connect(\"fixtures.db\")\r\n>>> db.execute('select * from compound_primary_key join facetable on rowid').fetchall()\r\nargs (21, None, None, None, None) kwargs {}\r\nargs (20, 'compound_primary_key', 'pk1', 'main', None) kwargs {}\r\nargs (20, 'compound_primary_key', 'pk2', 'main', None) kwargs {}\r\nargs (20, 'compound_primary_key', 'content', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'pk', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'created', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'planet_int', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'on_earth', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'state', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'city_id', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'neighborhood', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'tags', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'complex_array', 'main', None) kwargs {}\r\nargs (20, 'facetable', 'distinct_some_null', 'main', None) kwargs {}\r\n```\r\nThose `20` values (where 20 is `SQLITE_READ`) looked like they were checking permissions for the columns in the order they would be returned!\r\n\r\nThen I found a snag:\r\n\r\n```pycon\r\nIn [18]: db.execute('select 1 + 1 + (select max(rowid) from facetable)')\r\nargs (21, None, None, None, None) kwargs {}\r\nargs (31, None, 'max', None, None) kwargs {}\r\nargs (20, 'facetable', 'pk', 'main', None) kwargs {}\r\nargs (21, None, None, None, None) kwargs {}\r\nargs (20, 'facetable', '', None, None) kwargs {}\r\n```\r\nOnce a subselect is involved the order of the `20` checks no longer matches the order in which the columns are returned from the query.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813112546", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813112546, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzExMjU0Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-04T23:02:45Z", "updated_at": "2021-04-04T23:02:45Z", "author_association": "OWNER", "body": "I've done various pieces of research into this over the past few years. Capturing what I've discovered in this ticket.\r\n\r\nThe SQLite C API has functions that can help with this: https://www.sqlite.org/c3ref/column_database_name.html details those. But they're not exposed in the Python SQLite library.\r\n\r\nMaybe it would be possible to use them via `ctypes`? My hunch is that I would have to re-implement the full `sqlite3` module with `ctypes`, which sounds daunting.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1292#issuecomment-813109789", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1292", "id": 813109789, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzEwOTc4OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-04T22:37:47Z", "updated_at": "2021-04-04T22:37:47Z", "author_association": "OWNER", "body": "Could maybe replace this code: https://github.com/simonw/datasette/blob/0a7621f96f8ad14da17e7172e8a7bce24ef78966/datasette/utils/__init__.py#L1021-L1026", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849975810, "label": "Research ctypes.util.find_library('spatialite')"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/620#issuecomment-813167335", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/620", "id": 813167335, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzE2NzMzNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-05T03:57:22Z", "updated_at": "2021-04-05T03:57:22Z", "author_association": "OWNER", "body": "This may be obsoleted by #1293 - it looks like I may be able to auto-detect these foreign keys for arbitrary queries after all.", "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/1293#issuecomment-813164282", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813164282, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzE2NDI4Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-05T03:42:26Z", "updated_at": "2021-04-05T03:42:36Z", "author_association": "OWNER", "body": "Extracting variables with this trick appears to work OK, but you have to pass the correct variables to the `explain select...` query. Using `defaultdict` seems to work there:\r\n\r\n```pycon\r\n>>> rows = conn.execute('explain select * from repos where id = :id', defaultdict(int))\r\n>>> [dict(r) for r in rows if r['opcode'] == 'Variable']\r\n[{'addr': 2,\r\n 'opcode': 'Variable',\r\n 'p1': 1,\r\n 'p2': 1,\r\n 'p3': 0,\r\n 'p4': ':id',\r\n 'p5': 0,\r\n 'comment': None}]\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1293#issuecomment-813162622", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1293", "id": 813162622, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzE2MjYyMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-05T03:34:24Z", "updated_at": "2021-04-05T03:40:35Z", "author_association": "OWNER", "body": "This almost works, but throws errors with some queries (anything with a `rowid` column for example) - it needs a bunch of test coverage.\r\n```python\r\ndef columns_for_query(conn, sql):\r\n rows = conn.execute('explain ' + sql).fetchall()\r\n table_rootpage_by_register = {r['p1']: r['p2'] for r in rows if r['opcode'] == 'OpenRead'}\r\n names_by_rootpage = dict(\r\n conn.execute(\r\n 'select rootpage, name from sqlite_master where rootpage in ({})'.format(\r\n ', '.join(map(str, table_rootpage_by_register.values()))\r\n )\r\n )\r\n )\r\n columns_by_column_register = {}\r\n for row in rows:\r\n if row['opcode'] == 'Column':\r\n addr, opcode, table_id, cid, column_register, p4, p5, comment = row\r\n table = names_by_rootpage[table_rootpage_by_register[table_id]]\r\n columns_by_column_register[column_register] = (table, cid)\r\n result_row = [dict(r) for r in rows if r['opcode'] == 'ResultRow'][0]\r\n registers = list(range(result_row[\"p1\"], result_row[\"p1\"] + result_row[\"p2\"] - 1))\r\n all_column_names = {}\r\n for table in names_by_rootpage.values():\r\n table_xinfo = conn.execute('pragma table_xinfo({})'.format(table)).fetchall()\r\n for row in table_xinfo:\r\n all_column_names[(table, row[\"cid\"])] = row[\"name\"]\r\n final_output = []\r\n for r in registers:\r\n try:\r\n table, cid = columns_by_column_register[r]\r\n final_output.append((table, all_column_names[table, cid]))\r\n except KeyError:\r\n final_output.append((None, None))\r\n return final_output\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849978964, "label": "Show column metadata plus links for foreign keys on arbitrary query results"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1273#issuecomment-813061516", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1273", "id": 813061516, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMzA2MTUxNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-04T16:32:40Z", "updated_at": "2021-04-04T16:32:40Z", "author_association": "OWNER", "body": "Useful tutorial series from 2012: https://northredoubt.com/n/2012/01/20/spatialite-speed-test/", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 838382890, "label": "Refresh SpatiaLite documentation"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1287#issuecomment-812935384", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1287", "id": 812935384, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjkzNTM4NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-03T22:38:33Z", "updated_at": "2021-04-03T22:38:33Z", "author_association": "OWNER", "body": "https://twitter.com/llanga/status/1378431719934681094 looks like I should wait for 3.9.4, out in a few days.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849396758, "label": "Upgrade to Python 3.9.4"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/916#issuecomment-812941818", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/916", "id": 812941818, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjk0MTgxOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-03T23:43:11Z", "updated_at": "2021-04-03T23:43:11Z", "author_association": "OWNER", "body": "Relevant code is some of the most complex in all of Datasette.\r\n\r\nhttps://github.com/simonw/datasette/blob/0a7621f96f8ad14da17e7172e8a7bce24ef78966/datasette/views/table.py#L530-L594\r\n\r\nAnd\r\n\r\nhttps://github.com/simonw/datasette/blob/0a7621f96f8ad14da17e7172e8a7bce24ef78966/datasette/views/table.py#L743-L771\r\n\r\nI'll need to think hard about how to refactor this out into something more understandable before implementing previous links.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 672421411, "label": "Support reverse pagination (previous page, has-previous-items)"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/916#issuecomment-812941340", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/916", "id": 812941340, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjk0MTM0MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-03T23:38:37Z", "updated_at": "2021-04-03T23:38:37Z", "author_association": "OWNER", "body": "Same query again with `a, d, v` returns 0 results, which is also as we would want: it signifies that we are back to the very first page: https://latest.datasette.io/fixtures?sql=select+pk1%2C+pk2%2C+pk3%2C+content+from+compound_three_primary_keys+where+%28%28pk1+%3C+%3Ap0%29%0D%0A++or%0D%0A%28pk1+%3D+%3Ap0+and+pk2+%3C+%3Ap1%29%0D%0A++or%0D%0A%28pk1+%3D+%3Ap0+and+pk2+%3D+%3Ap1+and+pk3+%3C+%3Ap2%29%29+order+by+pk1+desc%2C+pk2+desc%2C+pk3+desc+limit+1+offset+99&p0=a&p1=d&p2=v", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 672421411, "label": "Support reverse pagination (previous page, has-previous-items)"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/916#issuecomment-812941112", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/916", "id": 812941112, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjk0MTExMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-03T23:35:55Z", "updated_at": "2021-04-03T23:35:55Z", "author_association": "OWNER", "body": "I tried flipping the direction of the sort and the comparison operators and got this: https://latest.datasette.io/fixtures?sql=select+pk1%2C+pk2%2C+pk3%2C+content+from+compound_three_primary_keys+where+%28%28pk1+%3C+%3Ap0%29%0D%0A++or%0D%0A%28pk1+%3D+%3Ap0+and+pk2+%3C+%3Ap1%29%0D%0A++or%0D%0A%28pk1+%3D+%3Ap0+and+pk2+%3D+%3Ap1+and+pk3+%3C+%3Ap2%29%29+order+by+pk1+desc%2C+pk2+desc%2C+pk3+desc+limit+1+offset+99&p0=a&p1=h&p2=r\r\n\r\n```sql\r\nselect pk1, pk2, pk3, content from compound_three_primary_keys where ((pk1 < :p0)\r\n or\r\n(pk1 = :p0 and pk2 < :p1)\r\n or\r\n(pk1 = :p0 and pk2 = :p1 and pk3 < :p2)) order by pk1 desc, pk2 desc, pk3 desc limit 1 offset 99\r\n```\r\nWhich returned `a-d-v` as desired. I messed around with it to find the `limit 1 offset 99` values.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 672421411, "label": "Support reverse pagination (previous page, has-previous-items)"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/916#issuecomment-812940907", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/916", "id": 812940907, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjk0MDkwNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-03T23:33:41Z", "updated_at": "2021-04-03T23:33:41Z", "author_association": "OWNER", "body": "Let's figure out the SQL for this. The most complex case is probably this one: https://latest.datasette.io/fixtures/compound_three_primary_keys?_next=a%2Ch%2Cr\r\n\r\nHere's the SQL for that page: https://latest.datasette.io/fixtures?sql=select+pk1%2C+pk2%2C+pk3%2C+content+from+compound_three_primary_keys+where+%28%28pk1+%3E+%3Ap0%29%0A++or%0A%28pk1+%3D+%3Ap0+and+pk2+%3E+%3Ap1%29%0A++or%0A%28pk1+%3D+%3Ap0+and+pk2+%3D+%3Ap1+and+pk3+%3E+%3Ap2%29%29+order+by+pk1%2C+pk2%2C+pk3+limit+101&p0=a&p1=h&p2=r\r\n\r\n```sql\r\nselect pk1, pk2, pk3, content from compound_three_primary_keys where ((pk1 > :p0)\r\n or\r\n(pk1 = :p0 and pk2 > :p1)\r\n or\r\n(pk1 = :p0 and pk2 = :p1 and pk3 > :p2)) order by pk1, pk2, pk3 limit 101\r\n```\r\nWhere `p0` is `a`, `p1` is `h` and `p2` is `r`.\r\n\r\nGiven the above, how would I figure out the correct previous link? It should be https://latest.datasette.io/fixtures/compound_three_primary_keys?_next=a%2Cd%2Cv - `a`, `d`, `v`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 672421411, "label": "Support reverse pagination (previous page, has-previous-items)"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/916#issuecomment-812940457", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/916", "id": 812940457, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjk0MDQ1Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-03T23:28:40Z", "updated_at": "2021-04-03T23:28:40Z", "author_association": "OWNER", "body": "I think my ideal implementation for this would be to reverse the order, grab the previous page-size-plus-one items, then return a `?_next=x` token that would provide the previous page sorted back in the expected default order.\r\n\r\nThe alternative would be to have a `?_previous=x` token which can be used to paginate backwards in reverse order, but I think this would be confusing as it would result in \"hit next page, then hit previous page\" returning you to a new state which features rows in the reverse order.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 672421411, "label": "Support reverse pagination (previous page, has-previous-items)"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/pull/1291#issuecomment-812815358", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1291", "id": 812815358, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjgxNTM1OA==", "user": {"value": 22429695, "label": "codecov[bot]"}, "created_at": "2021-04-03T05:32:50Z", "updated_at": "2021-06-05T19:48:30Z", "author_association": "NONE", "body": "# [Codecov](https://codecov.io/gh/simonw/datasette/pull/1291?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report\n> Merging [#1291](https://codecov.io/gh/simonw/datasette/pull/1291?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (8789157) into [main](https://codecov.io/gh/simonw/datasette/commit/0a7621f96f8ad14da17e7172e8a7bce24ef78966?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (0a7621f) will **not change** coverage.\n> The diff coverage is `n/a`.\n\n> :exclamation: Current head 8789157 differs from pull request most recent head 9bf089f. Consider uploading reports for the commit 9bf089f to get more accurate results\n[![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/1291/graphs/tree.svg?width=650&height=150&src=pr&token=eSahVY7kw1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)](https://codecov.io/gh/simonw/datasette/pull/1291?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)\n\n```diff\n@@ Coverage Diff @@\n## main #1291 +/- ##\n=======================================\n Coverage 91.51% 91.51% \n=======================================\n Files 34 34 \n Lines 4255 4255 \n=======================================\n Hits 3894 3894 \n Misses 361 361 \n```\n\n\n\n------\n\n[Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/1291?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).\n> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)\n> `\u0394 = absolute (impact)`, `\u00f8 = not affected`, `? = missing data`\n> Powered by [Codecov](https://codecov.io/gh/simonw/datasette/pull/1291?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Last update [0a7621f...9bf089f](https://codecov.io/gh/simonw/datasette/pull/1291?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849582643, "label": "Update docs: explain allow_download setting"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/502#issuecomment-812813732", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/502", "id": 812813732, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjgxMzczMg==", "user": {"value": 5413548, "label": "louispotok"}, "created_at": "2021-04-03T05:16:54Z", "updated_at": "2021-04-03T05:16:54Z", "author_association": "CONTRIBUTOR", "body": "For what it's worth, if anyone finds this in the future, I was having the same issue. \r\n\r\nAfter digging through the code, it turned out that the database download is only available if it the db served in immutable mode, so `datasette serve -i xyz.db` rather than the doc's quickstart recommendation of `datasette serve xyz.db`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 453131917, "label": "Exporting sqlite database(s)?"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/916#issuecomment-812804998", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/916", "id": 812804998, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjgwNDk5OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-03T03:47:45Z", "updated_at": "2021-04-03T03:47:45Z", "author_association": "OWNER", "body": "I found one example of an implementation of reversed keyset pagination here: https://github.com/tvainika/objection-keyset-pagination/blob/cb21a493c96daa6e63c302efae6718d09aa11661/index.js#L74-L79", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 672421411, "label": "Support reverse pagination (previous page, has-previous-items)"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/pull/1290#issuecomment-812804178", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1290", "id": 812804178, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjgwNDE3OA==", "user": {"value": 22429695, "label": "codecov[bot]"}, "created_at": "2021-04-03T03:39:16Z", "updated_at": "2021-04-03T03:41:29Z", "author_association": "NONE", "body": "# [Codecov](https://codecov.io/gh/simonw/datasette/pull/1290?src=pr&el=h1) Report\n> Merging [#1290](https://codecov.io/gh/simonw/datasette/pull/1290?src=pr&el=desc) (2fb1e42) into [main](https://codecov.io/gh/simonw/datasette/commit/87b583a128986982552421d2510e467e74ac5046?el=desc) (87b583a) will **not change** coverage.\n> The diff coverage is `n/a`.\n\n[![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/1290/graphs/tree.svg?width=650&height=150&src=pr&token=eSahVY7kw1)](https://codecov.io/gh/simonw/datasette/pull/1290?src=pr&el=tree)\n\n```diff\n@@ Coverage Diff @@\n## main #1290 +/- ##\n=======================================\n Coverage 91.51% 91.51% \n=======================================\n Files 34 34 \n Lines 4255 4255 \n=======================================\n Hits 3894 3894 \n Misses 361 361 \n```\n\n\n\n------\n\n[Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/1290?src=pr&el=continue).\n> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)\n> `\u0394 = absolute (impact)`, `\u00f8 = not affected`, `? = missing data`\n> Powered by [Codecov](https://codecov.io/gh/simonw/datasette/pull/1290?src=pr&el=footer). Last update [87b583a...2fb1e42](https://codecov.io/gh/simonw/datasette/pull/1290?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849568079, "label": "Use pytest-xdist to speed up tests"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1289#issuecomment-812803256", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1289", "id": 812803256, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjgwMzI1Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-03T03:29:25Z", "updated_at": "2021-04-03T03:29:25Z", "author_association": "OWNER", "body": "https://github.com/simonw/datasette/actions/runs/713207828 ran with `pytest-xdist` in 4m22s:\r\n\r\n\r\n\r\nHere's the test suite running on regular `pytest` in 5m13s:\r\n\r\n\r\n\r\nNot a huge speed-up because there are only 2 available cores in the GitHub Actions environment, but still worthwhile - especially since this lets people run in parallel on their own laptops.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849543502, "label": "Speed up tests with pytest-xdist"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1245#issuecomment-812711365", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1245", "id": 812711365, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjcxMTM2NQ==", "user": {"value": 1111743, "label": "jungle-boogie"}, "created_at": "2021-04-02T20:53:35Z", "updated_at": "2021-04-02T20:53:35Z", "author_association": "NONE", "body": "Yes, I agree. \r\n\r\nAlternatively, maybe the header could be at the top and bottom, above the next page button.\r\n\r\nMaybe even have the header 50 records down?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 817544251, "label": "Sticky table column headers would be useful, especially on the query page"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1255#issuecomment-812710120", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1255", "id": 812710120, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjcxMDEyMA==", "user": {"value": 1111743, "label": "jungle-boogie"}, "created_at": "2021-04-02T20:50:08Z", "updated_at": "2021-04-02T20:50:08Z", "author_association": "NONE", "body": "Hello again,\r\n\r\nI was able to get my facets running with this `settings.json`, which was lifted from one of Simon's datasette's and slightly modified.\r\n\r\n```\r\n{\r\n \"default_page_size\": 100,\r\n \"max_returned_rows\": 1000,\r\n \"num_sql_threads\": 3,\r\n \"sql_time_limit_ms\": 9000,\r\n \"default_facet_size\": 10,\r\n \"facet_time_limit_ms\": 9000,\r\n \"facet_suggest_time_limit_ms\": 500,\r\n \"hash_urls\": false,\r\n \"allow_facet\": true,\r\n \"suggest_facets\": false,\r\n \"default_cache_ttl\": 5,\r\n \"default_cache_ttl_hashed\": 31536000,\r\n \"cache_size_kb\": 0,\r\n \"allow_csv_stream\": true,\r\n \"max_csv_mb\": 100,\r\n \"truncate_cells_html\": 2048,\r\n \"template_debug\": false,\r\n \"base_url\": \"/\"\r\n}\r\n```", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 826700095, "label": "Facets timing out but work when filtering"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1289#issuecomment-812768915", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1289", "id": 812768915, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjc2ODkxNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-03T00:59:15Z", "updated_at": "2021-04-03T00:59:26Z", "author_association": "OWNER", "body": "Looks like `-n auto` only detected two cores on GitHub Actions: https://github.com/simonw/datasette/runs/2257597137?check_suite_focus=true\r\n```\r\n============================= test session starts ==============================\r\nplatform linux -- Python 3.7.10, pytest-6.2.2, py-1.10.0, pluggy-0.13.1\r\nSQLite: 3.31.1\r\nrootdir: /home/runner/work/datasette/datasette, configfile: pytest.ini\r\nplugins: xdist-2.2.1, timeout-1.4.2, forked-1.3.0, asyncio-0.14.0\r\ngw0 I / gw1 I\r\ngw0 [878] / gw1 [878]\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849543502, "label": "Speed up tests with pytest-xdist"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1289#issuecomment-812767460", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1289", "id": 812767460, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjc2NzQ2MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-03T00:48:26Z", "updated_at": "2021-04-03T00:48:26Z", "author_association": "OWNER", "body": "On my Mac `pytest-xdist` ran the test suite (minus two tests) in 59s, as opposed to 2m23s without xdist.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849543502, "label": "Speed up tests with pytest-xdist"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/916#issuecomment-812742462", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/916", "id": 812742462, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjc0MjQ2Mg==", "user": {"value": 1111743, "label": "jungle-boogie"}, "created_at": "2021-04-02T22:37:27Z", "updated_at": "2021-04-02T22:37:27Z", "author_association": "NONE", "body": "Yes, this would be nice!\r\n\r\nI using Datasette v0.56 and don't see a previous page button.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 672421411, "label": "Support reverse pagination (previous page, has-previous-items)"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1255#issuecomment-812680519", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1255", "id": 812680519, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjY4MDUxOQ==", "user": {"value": 1111743, "label": "jungle-boogie"}, "created_at": "2021-04-02T19:37:57Z", "updated_at": "2021-04-02T19:37:57Z", "author_association": "NONE", "body": "Hello,\r\n\r\nI'm also experiencing a timeout in my environment. I don't know if it's because I need more indexes or a more powerful system.\r\n\r\nMy data has 1,271,111 and when I try to create a facet, there's a time out. I've tried this on two different rows that should significantly filter down data: `CITY` and `PARTY_REG`.\r\n\r\nSimon's johns_hopkins_csse_daily_reports has more rows and it setup with two facets on load. He does have four indexes created, though. Do I need more indexes?\r\n\r\nI have one simple one so far:\r\n```\r\nCREATE INDEX [idx_party_reg]\r\n ON [county_active] ([PARTY_REG]);\r\n```\r\n\r\nI'm running Datasette 0.56 installed via pip with Python 3.7.3.\r\n\r\n`4.19.0-10-amd64 #1 SMP Debian 4.19.132-1 (2020-07-24) x86_64 GNU/Linux`\r\n\r\n```\r\n$ cat /etc/os-release\r\nPRETTY_NAME=\"Debian GNU/Linux 10 (buster)\"\r\nNAME=\"Debian GNU/Linux\"\r\nVERSION_ID=\"10\"\r\nVERSION=\"10 (buster)\"\r\nVERSION_CODENAME=buster\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 826700095, "label": "Facets timing out but work when filtering"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1286#issuecomment-812679221", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1286", "id": 812679221, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjY3OTIyMQ==", "user": {"value": 192568, "label": "mroswell"}, "created_at": "2021-04-02T19:34:01Z", "updated_at": "2021-04-02T19:34:01Z", "author_association": "CONTRIBUTOR", "body": "This shows the city in a different color (and not the comma), but I get the idea, and I like it. (Ooh, could be nice to have the gear have an option in array fields to show as bullets or commas or semicolons...)", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849220154, "label": "Better default display of arrays of items"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1287#issuecomment-812665092", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1287", "id": 812665092, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjY2NTA5Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-02T18:54:29Z", "updated_at": "2021-04-02T18:54:29Z", "author_association": "OWNER", "body": "`python:3.9.3-slim-buster` isn't on Docker Hub yet either.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849396758, "label": "Upgrade to Python 3.9.4"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1286#issuecomment-812664443", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1286", "id": 812664443, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjY2NDQ0Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-02T18:52:45Z", "updated_at": "2021-04-02T18:52:51Z", "author_association": "OWNER", "body": "Idea: default to displaying single-dimension JSON arrays of strings as a comma-separated list but show the comma in a different colour - something like this:\r\n\r\n\r\n\r\nI used this HTML for the prototype (re-using `.type-int` just to get the colour):\r\n```html\r\ntag1, tag2 | \r\n```", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849220154, "label": "Better default display of arrays of items"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1286#issuecomment-812663107", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1286", "id": 812663107, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjY2MzEwNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-02T18:49:22Z", "updated_at": "2021-04-02T18:49:22Z", "author_association": "OWNER", "body": "This makes senses - showing an array as `[\"blah\", \"blah2\", \"blah3\"]` isn't particularly human-friendly!", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849220154, "label": "Better default display of arrays of items"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1287#issuecomment-812662583", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1287", "id": 812662583, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjY2MjU4Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-02T18:47:59Z", "updated_at": "2021-04-02T18:47:59Z", "author_association": "OWNER", "body": "Once again having tests for the Dockerfile as seen in #1272 would be useful here.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849396758, "label": "Upgrade to Python 3.9.4"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1287#issuecomment-812662026", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1287", "id": 812662026, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjY2MjAyNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-02T18:46:20Z", "updated_at": "2021-04-02T18:46:20Z", "author_association": "OWNER", "body": "https://devcenter.heroku.com/articles/python-support#supported-runtimes looks like Heroku still only have 3.9.2 for the moment.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849396758, "label": "Upgrade to Python 3.9.4"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1287#issuecomment-812661269", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1287", "id": 812661269, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMjY2MTI2OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-04-02T18:45:08Z", "updated_at": "2021-04-02T18:45:19Z", "author_association": "OWNER", "body": "A few places:\r\n\r\nhttps://github.com/simonw/datasette/blob/7b1a9a1999eb9326ce8ec830d75ac200e5279c46/Dockerfile#L1\r\n\r\nhttps://github.com/simonw/datasette/blob/8e18c7943181f228ce5ebcea48deb59ce50bee1f/datasette/utils/__init__.py#L350\r\n\r\nhttps://github.com/simonw/datasette/blob/8e18c7943181f228ce5ebcea48deb59ce50bee1f/tests/test_package.py#L14\r\n\r\nhttps://github.com/simonw/datasette/blob/8e18c7943181f228ce5ebcea48deb59ce50bee1f/datasette/publish/heroku.py#L177-L178", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849396758, "label": "Upgrade to Python 3.9.4"}, "performed_via_github_app": null}
{"html_url": "https://github.com/dogsheep/dogsheep-photos/pull/31#issuecomment-811362316", "issue_url": "https://api.github.com/repos/dogsheep/dogsheep-photos/issues/31", "id": 811362316, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMTM2MjMxNg==", "user": {"value": 871250, "label": "PabloLerma"}, "created_at": "2021-03-31T19:14:39Z", "updated_at": "2021-03-31T19:14:39Z", "author_association": "NONE", "body": "\ud83d\udc4b could I help somehow for this to be merged? As Big Sur is going to be more used as the time goes I think it would be nice to merge and publish a new version. Nice work!", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 771511344, "label": "Update for Big Sur"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1276#issuecomment-811209922", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1276", "id": 811209922, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMTIwOTkyMg==", "user": {"value": 1314318, "label": "justinallen"}, "created_at": "2021-03-31T16:27:26Z", "updated_at": "2021-03-31T16:27:26Z", "author_association": "NONE", "body": "Fantastic. Thank you! ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 841456306, "label": "Invalid SQL: \"no such table: pragma_database_list\" on database page"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/526#issuecomment-810943882", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/526", "id": 810943882, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMDk0Mzg4Mg==", "user": {"value": 701, "label": "jokull"}, "created_at": "2021-03-31T10:03:55Z", "updated_at": "2021-03-31T10:03:55Z", "author_association": "NONE", "body": "+1 on using nested queries to achieve this! Would be great as streaming CSV is an amazing feature.\r\n\r\nSome UX/DX details:\r\n\r\nI was expecting it to work to simply add `&_stream=on` to custom SQL queries because the docs say \r\n\r\n> Any Datasette table, view or **custom SQL query** can be exported as CSV.\r\n\r\nAfter a bit of testing back and forth I realized streaming only works for full tables. \r\n\r\nWould love this feature because I'm using `pandas.read_csv` to paint graphs from custom queries and the graphs are cut off because of the 1000 row limit. ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 459882902, "label": "Stream all results for arbitrary SQL and canned queries"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1284#issuecomment-810779928", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1284", "id": 810779928, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMDc3OTkyOA==", "user": {"value": 192568, "label": "mroswell"}, "created_at": "2021-03-31T05:40:12Z", "updated_at": "2021-03-31T05:40:12Z", "author_association": "CONTRIBUTOR", "body": "Maybe the addition of two template files: 'one_database_index.html' and 'one_table_index.html' would be a better idea than the documentation diff idea. (They could include commented instructions to rename the preferred template 'index.html', along with any other necessary guidance.)", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 845794436, "label": "Feature or Documentation Request: Individual table as home page template"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1284#issuecomment-810740486", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1284", "id": 810740486, "node_id": "MDEyOklzc3VlQ29tbWVudDgxMDc0MDQ4Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-03-31T03:57:55Z", "updated_at": "2021-03-31T03:57:55Z", "author_association": "OWNER", "body": "You're right, doing this is really hard at the moment - I'm not sure I know how I would tackle this either, and it's something I've wanted in the past!\r\n\r\nI'll have a think about this one.", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 845794436, "label": "Feature or Documentation Request: Individual table as home page template"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/pull/1282#issuecomment-809670294", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1282", "id": 809670294, "node_id": "MDEyOklzc3VlQ29tbWVudDgwOTY3MDI5NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-03-29T19:57:29Z", "updated_at": "2021-03-29T19:57:29Z", "author_association": "OWNER", "body": "Thanks!", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 843739658, "label": "Fix little typo"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/pull/1282#issuecomment-809667320", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1282", "id": 809667320, "node_id": "MDEyOklzc3VlQ29tbWVudDgwOTY2NzMyMA==", "user": {"value": 22429695, "label": "codecov[bot]"}, "created_at": "2021-03-29T19:52:35Z", "updated_at": "2021-03-29T19:52:35Z", "author_association": "NONE", "body": "# [Codecov](https://codecov.io/gh/simonw/datasette/pull/1282?src=pr&el=h1) Report\n> Merging [#1282](https://codecov.io/gh/simonw/datasette/pull/1282?src=pr&el=desc) (08f7427) into [main](https://codecov.io/gh/simonw/datasette/commit/0486303b60ce2784fd2e2ecdbecf304b7d6e6659?el=desc) (0486303) will **not change** coverage.\n> The diff coverage is `n/a`.\n\n[![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/1282/graphs/tree.svg?width=650&height=150&src=pr&token=eSahVY7kw1)](https://codecov.io/gh/simonw/datasette/pull/1282?src=pr&el=tree)\n\n```diff\n@@ Coverage Diff @@\n## main #1282 +/- ##\n=======================================\n Coverage 91.51% 91.51% \n=======================================\n Files 34 34 \n Lines 4255 4255 \n=======================================\n Hits 3894 3894 \n Misses 361 361 \n```\n\n\n\n------\n\n[Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/1282?src=pr&el=continue).\n> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)\n> `\u0394 = absolute (impact)`, `\u00f8 = not affected`, `? = missing data`\n> Powered by [Codecov](https://codecov.io/gh/simonw/datasette/pull/1282?src=pr&el=footer). Last update [0486303...08f7427](https://codecov.io/gh/simonw/datasette/pull/1282?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 843739658, "label": "Fix little typo"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/696#issuecomment-809548363", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/696", "id": 809548363, "node_id": "MDEyOklzc3VlQ29tbWVudDgwOTU0ODM2Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-03-29T17:04:19Z", "updated_at": "2021-03-29T17:04:19Z", "author_association": "OWNER", "body": "I tried this just now against Datasette 0.56 with the new Dockerfile from #1249 (that uses SQLite and SpatiaLite installed with `apt-get install`) and the tests all passed.", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 576722115, "label": "Single failing unit test when run inside the Docker image"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/pull/1031#issuecomment-809010713", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1031", "id": 809010713, "node_id": "MDEyOklzc3VlQ29tbWVudDgwOTAxMDcxMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-03-29T01:46:45Z", "updated_at": "2021-03-29T01:46:45Z", "author_association": "OWNER", "body": "Sorry I didn't get to this PR sooner. I've joint-credited you in the release notes for this fix: https://docs.datasette.io/en/stable/changelog.html#v0-56", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 724369025, "label": "Fallback to databases in inspect-data.json when no -i options are passed"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1281#issuecomment-809009580", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1281", "id": 809009580, "node_id": "MDEyOklzc3VlQ29tbWVudDgwOTAwOTU4MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-03-29T01:41:48Z", "updated_at": "2021-03-29T01:41:48Z", "author_association": "OWNER", "body": "https://github.com/simonw/datasette/runs/2214871602?check_suite_focus=true worked:\r\n\r\n\r\n\r\nHere's the 0.56 image on Docker Hub: https://hub.docker.com/layers/datasetteproject/datasette/0.56/images/sha256-701fc0f299a0ea79434a4852c46dab351254b9ac25dbe3c5f36fd5360caf52f9?context=explore", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 842881221, "label": "Latest Datasette tags missing from Docker Hub"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1281#issuecomment-809008760", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1281", "id": 809008760, "node_id": "MDEyOklzc3VlQ29tbWVudDgwOTAwODc2MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-03-29T01:38:21Z", "updated_at": "2021-03-29T01:38:21Z", "author_association": "OWNER", "body": "Got this error:\r\n```\r\n\"docker tag\" requires exactly 2 arguments.\r\nSee 'docker tag --help'.\r\n\r\nUsage: docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]\r\n\r\nCreate a tag TARGET_IMAGE that refers to SOURCE_IMAGE\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 842881221, "label": "Latest Datasette tags missing from Docker Hub"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1281#issuecomment-809007255", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1281", "id": 809007255, "node_id": "MDEyOklzc3VlQ29tbWVudDgwOTAwNzI1NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-03-29T01:32:18Z", "updated_at": "2021-03-29T01:32:18Z", "author_association": "OWNER", "body": "I'm going to build a new GitHub Actions workflow for this that lets me manually specify a tag to build and push as a Docker image.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 842881221, "label": "Latest Datasette tags missing from Docker Hub"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1281#issuecomment-809001653", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1281", "id": 809001653, "node_id": "MDEyOklzc3VlQ29tbWVudDgwOTAwMTY1Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-03-29T01:08:31Z", "updated_at": "2021-03-29T01:08:31Z", "author_association": "OWNER", "body": "I'm going to attempt to fix this manually for the 0.56 release, by building and tagging it by hand and then pushing the 0.56 tag to Docker Hub.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 842881221, "label": "Latest Datasette tags missing from Docker Hub"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1281#issuecomment-809001273", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1281", "id": 809001273, "node_id": "MDEyOklzc3VlQ29tbWVudDgwOTAwMTI3Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-03-29T01:06:45Z", "updated_at": "2021-03-29T01:06:45Z", "author_association": "OWNER", "body": "https://docs.docker.com/engine/reference/commandline/push/#push-all-tags-of-an-image\r\n\r\n> Use the `-a` (or `--all-tags`) option to push all tags of a local image.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 842881221, "label": "Latest Datasette tags missing from Docker Hub"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1281#issuecomment-809000903", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1281", "id": 809000903, "node_id": "MDEyOklzc3VlQ29tbWVudDgwOTAwMDkwMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-03-29T01:05:10Z", "updated_at": "2021-03-29T01:05:10Z", "author_association": "OWNER", "body": "https://github.com/simonw/datasette/runs/1763835467?check_suite_focus=true for Datasette 0.54 worked, and the output included this:\r\n\r\n```\r\nSuccessfully tagged ***/datasette:0.54\r\nThe push refers to repository [docker.io/***/datasette]\r\naedd33c6b161: Preparing\r\n...\r\naedd33c6b161: Pushed\r\n0.54: digest: sha256:65c7e579d1c29755dac5c1ca86b1e97fa88c48bd3d724ac3e02988d0da296140 size: 2005\r\naedd33c6b161: Preparing\r\n...\r\n5dacd731af1b: Layer already exists\r\nlatest: digest: sha256:65c7e579d1c29755dac5c1ca86b1e97fa88c48bd3d724ac3e02988d0da296140 size: 2005\r\n```\r\nHere's that same section of output from the 0.56 release:\r\n```\r\nSuccessfully tagged ***/datasette:0.56\r\nUsing default tag: latest\r\nThe push refers to repository [docker.io/***/datasette]\r\n4d4a9976adcc: Preparing\r\n...\r\n9b2132a0d5cf: Pushed\r\nlatest: digest: sha256:2250d0fbe57b1d615a8d6df0c9d43deb9533532e00bac68854773d8ff8dcf00a size: 1793\r\n```\r\nThe difference here is the \"Using default tag: latest\" bit.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 842881221, "label": "Latest Datasette tags missing from Docker Hub"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1281#issuecomment-808999525", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1281", "id": 808999525, "node_id": "MDEyOklzc3VlQ29tbWVudDgwODk5OTUyNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-03-29T01:00:38Z", "updated_at": "2021-03-29T01:00:38Z", "author_association": "OWNER", "body": "Here's the diff between `Dockerfile` in 0.54.1 and 0.56: https://github.com/simonw/datasette/compare/0.54.1...0.56#diff-551d1fcf87f78cc3bc18a7b332a4dc5d8773a512062df881c5aba28a6f5c48d7\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": 842881221, "label": "Latest Datasette tags missing from Docker Hub"}, "performed_via_github_app": null}