issue_comments
9,947 rows sorted by issue_url
This data as json, CSV (advanced)
id | html_url | issue_url ▼ | node_id | user | created_at | updated_at | author_association | body | reactions | issue | performed_via_github_app |
---|---|---|---|---|---|---|---|---|---|---|---|
865160132 | https://github.com/simonw/datasette/pull/1368#issuecomment-865160132 | https://api.github.com/repos/simonw/datasette/issues/1368 | MDEyOklzc3VlQ29tbWVudDg2NTE2MDEzMg== | simonw 9599 | 2021-06-21T16:07:06Z | 2021-06-21T16:08:48Z | OWNER | A few tests failed - Black, the test that checks the docs mention the new hook - the most interesting failing test looks like this one: ``` updated_metadata["databases"]["fixtures"]["queries"]["magic_parameters"][ "allow" ] = (allow if "query" in permissions else deny) > cascade_app_client.ds._metadata = updated_metadata E AttributeError: can't set attribute ``` From https://github.com/simonw/datasette/blob/0a7621f96f8ad14da17e7172e8a7bce24ef78966/tests/test_permissions.py#L439-L467 This test is directly manipulating `_metadata` purely for the purposes of simulating different permissions - I think updating it to manipulate `_local_metadata` instead would fix that. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | DRAFT: A new plugin hook for dynamic metadata 913865304 | |
865204472 | https://github.com/simonw/datasette/pull/1368#issuecomment-865204472 | https://api.github.com/repos/simonw/datasette/issues/1368 | MDEyOklzc3VlQ29tbWVudDg2NTIwNDQ3Mg== | brandonrobertz 2670795 | 2021-06-21T17:11:37Z | 2021-06-21T17:11:37Z | CONTRIBUTOR | If this is a concept ACK then I will move onto fixing the tests (adding new ones) and updating the documentation for the new plugin hook. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | DRAFT: A new plugin hook for dynamic metadata 913865304 | |
867102944 | https://github.com/simonw/datasette/pull/1368#issuecomment-867102944 | https://api.github.com/repos/simonw/datasette/issues/1368 | MDEyOklzc3VlQ29tbWVudDg2NzEwMjk0NA== | simonw 9599 | 2021-06-23T19:32:01Z | 2021-06-23T19:32:01Z | OWNER | Yes, let's move ahead with getting this into an alpha. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | DRAFT: A new plugin hook for dynamic metadata 913865304 | |
869068554 | https://github.com/simonw/datasette/pull/1368#issuecomment-869068554 | https://api.github.com/repos/simonw/datasette/issues/1368 | MDEyOklzc3VlQ29tbWVudDg2OTA2ODU1NA== | simonw 9599 | 2021-06-26T22:23:57Z | 2021-06-26T22:23:57Z | OWNER | The only test failure is Black. I'm going to merge this and then reformat. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | DRAFT: A new plugin hook for dynamic metadata 913865304 | |
856208637 | https://github.com/simonw/datasette/issues/1369#issuecomment-856208637 | https://api.github.com/repos/simonw/datasette/issues/1369 | MDEyOklzc3VlQ29tbWVudDg1NjIwODYzNw== | simonw 9599 | 2021-06-07T19:47:23Z | 2021-06-07T19:47:23Z | OWNER | No point in showing the IDs twice if the blue label doesn't differ from the gray ID | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Don't show foreign key IDs twice if no label 913900374 | |
345750135 | https://github.com/simonw/datasette/issues/137#issuecomment-345750135 | https://api.github.com/repos/simonw/datasette/issues/137 | MDEyOklzc3VlQ29tbWVudDM0NTc1MDEzNQ== | simonw 9599 | 2017-11-20T16:30:56Z | 2018-07-10T17:53:13Z | OWNER | One possible route: introduce prefixes eg `?a.Trees.age__gt=5&a.Trees._group_count=qSpecies&b.Trees.age__gt=10&b.Trees._group_count=qSpecies` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Ability to combine multiple SQL queries on a single graph 275415799 | |
857139881 | https://github.com/simonw/datasette/pull/1370#issuecomment-857139881 | https://api.github.com/repos/simonw/datasette/issues/1370 | MDEyOklzc3VlQ29tbWVudDg1NzEzOTg4MQ== | simonw 9599 | 2021-06-08T20:58:41Z | 2021-06-08T20:58:41Z | OWNER | We can remove a bunch of unnecessary `str(path)` calls too - this search finds a bunch of possible candidates: https://ripgrep.datasette.io/-/ripgrep?pattern=str%5C%28.*%28db%7Cpath%29&glob=datasette%2F**%2F*.py | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Ensure db.path is a string before trying to insert into internal database 914130834 | |
857298526 | https://github.com/simonw/datasette/pull/1370#issuecomment-857298526 | https://api.github.com/repos/simonw/datasette/issues/1370 | MDEyOklzc3VlQ29tbWVudDg1NzI5ODUyNg== | eyeseast 25778 | 2021-06-09T01:18:59Z | 2021-06-09T01:18:59Z | CONTRIBUTOR | I'm happy to grab some or all of these in this PR, if you want. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Ensure db.path is a string before trying to insert into internal database 914130834 | |
858099514 | https://github.com/simonw/datasette/issues/1371#issuecomment-858099514 | https://api.github.com/repos/simonw/datasette/issues/1371 | MDEyOklzc3VlQ29tbWVudDg1ODA5OTUxNA== | simonw 9599 | 2021-06-09T21:03:49Z | 2021-06-09T21:03:49Z | OWNER | I'll release these as an alpha straight away - it makes sense to have plugin hook changes available for people to test as alpha dependencies ASAP. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Menu plugin hooks should include the request 915455228 | |
857684605 | https://github.com/simonw/datasette/pull/1373#issuecomment-857684605 | https://api.github.com/repos/simonw/datasette/issues/1373 | MDEyOklzc3VlQ29tbWVudDg1NzY4NDYwNQ== | codecov[bot] 22429695 | 2021-06-09T13:15:31Z | 2021-06-13T15:34:07Z | NONE | # [Codecov](https://codecov.io/gh/simonw/datasette/pull/1373?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report > Merging [#1373](https://codecov.io/gh/simonw/datasette/pull/1373?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (d117ba7) into [main](https://codecov.io/gh/simonw/datasette/commit/03418ee037057aa85204f5a3feb2066cbb6a9b3e?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (03418ee) will **increase** coverage by `7.65%`. > The diff coverage is `93.29%`. > :exclamation: Current head d117ba7 differs from pull request most recent head 51ff366. Consider uploading reports for the commit 51ff366 to get more accurate results [![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/1373/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/1373?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) ```diff @@ Coverage Diff @@ ## main #1373 +/- ## ========================================== + Coverage 84.02% 91.68% +7.65% ========================================== Files 28 34 +6 Lines 3774 4340 +566 ========================================== + Hits 3171 3979 +808 + Misses 603 361 -242 ``` | [Impacted Files](https://codecov.io/gh/simonw/datasette/pull/1373?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | | |---|---|---| | [datasette/inspect.py](https://codecov.io/gh/simonw/datasette/pull/1373/diff?src=pr&el=tree&utm_medium=r… | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Update trustme requirement from <0.8,>=0.7 to >=0.7,<0.9 916183914 | |
859572791 | https://github.com/simonw/datasette/pull/1374#issuecomment-859572791 | https://api.github.com/repos/simonw/datasette/issues/1374 | MDEyOklzc3VlQ29tbWVudDg1OTU3Mjc5MQ== | codecov[bot] 22429695 | 2021-06-11T13:12:58Z | 2021-06-11T13:12:58Z | NONE | # [Codecov](https://codecov.io/gh/simonw/datasette/pull/1374?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report > Merging [#1374](https://codecov.io/gh/simonw/datasette/pull/1374?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (0ef0dd5) into [main](https://codecov.io/gh/simonw/datasette/commit/cd7678fde65319d7b6955ce9f4678ba4b9e64b66?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (cd7678f) will **not change** coverage. > The diff coverage is `n/a`. [![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/1374/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/1374?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) ```diff @@ Coverage Diff @@ ## main #1374 +/- ## ======================================= Coverage 91.68% 91.68% ======================================= Files 34 34 Lines 4340 4340 ======================================= Hits 3979 3979 Misses 361 361 ``` ------ [Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/1374?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). > **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) > `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data` > Powered by [Codecov](https://codecov… | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Bump black from 21.5b2 to 21.6b0 918730335 | |
860230385 | https://github.com/simonw/datasette/issues/1375#issuecomment-860230385 | https://api.github.com/repos/simonw/datasette/issues/1375 | MDEyOklzc3VlQ29tbWVudDg2MDIzMDM4NQ== | simonw 9599 | 2021-06-13T15:37:49Z | 2021-06-13T15:37:49Z | OWNER | There is a feature for this at the moment, but it's a little bit hidden: you can use `?_json=col` to tell Datasette that you would like a specific column to be exported as nested JSON: https://docs.datasette.io/en/stable/json_api.html#special-json-arguments I considered trying to make this automatic - so it detects columns that appear to contain valid JSON and outputs them as nested objects - but the problem with that is that it can lead to inconsistent results - you might hit the API and find that not every column contains valid JSON (compared to the previous day) resulting in the API retuning string instead of the expected dictionary and breaking your code. | {"total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JSON export dumps JSON fields as TEXT 919508498 | |
860548546 | https://github.com/simonw/datasette/issues/1375#issuecomment-860548546 | https://api.github.com/repos/simonw/datasette/issues/1375 | MDEyOklzc3VlQ29tbWVudDg2MDU0ODU0Ng== | frafra 4068 | 2021-06-14T09:41:59Z | 2021-06-14T09:41:59Z | NONE | > There is a feature for this at the moment, but it's a little bit hidden: you can use `?_json=col` to tell > Datasette that you would like a specific column to be exported as nested JSON: https://docs.datasette.io/en/stable/json_api.html#special-json-arguments Thanks :) > I considered trying to make this automatic - so it detects columns that appear to contain valid JSON and outputs them as nested objects - but the problem with that is that it can lead to inconsistent results - you might hit the API and find that not every column contains valid JSON (compared to the previous day) resulting in the API retuning string instead of the expected dictionary and breaking your code. If a developer is not sure if the JSON fields are valid, but then retrieves and parse them, it should handle errors too. Handling inconsistent data is necessary due to the nature of SQLite. A global or dataset option to render the data as they have been defined (JSON, boolean, etc.) when requesting JSON could allow the user to download a regular JSON from the browser without having to rely on APIs. I would guess someone could just make a custom template with an extra JSON-parsed download button otherwise :) | {"total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JSON export dumps JSON fields as TEXT 919508498 | |
860229226 | https://github.com/simonw/datasette/issues/1376#issuecomment-860229226 | https://api.github.com/repos/simonw/datasette/issues/1376 | MDEyOklzc3VlQ29tbWVudDg2MDIyOTIyNg== | simonw 9599 | 2021-06-13T15:29:45Z | 2021-06-13T15:29:45Z | OWNER | Oh good catch - this is a SQLite version issue. The `fixtures.db` file used on https://latest.datasette.io/ includes a generated column (for testing purposes) which is a feature added in SQLite 3.31.0 on 2020-01-22. https://latest.datasette.io/-/versions But... it looks like the packaged Datasette Docker container doesn't have that SQLite version! I should fix that. I'm renaming this issue. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Official Datasette Docker image should use SQLite >= 3.31.0 (for generated columns) 919822817 | |
860229397 | https://github.com/simonw/datasette/issues/1376#issuecomment-860229397 | https://api.github.com/repos/simonw/datasette/issues/1376 | MDEyOklzc3VlQ29tbWVudDg2MDIyOTM5Nw== | simonw 9599 | 2021-06-13T15:31:02Z | 2021-06-13T15:31:02Z | OWNER | Alternative fix would be to update that section of the documentation - if the container upgrade proves tricky I can fall back on that. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Official Datasette Docker image should use SQLite >= 3.31.0 (for generated columns) 919822817 | |
860230663 | https://github.com/simonw/datasette/issues/1376#issuecomment-860230663 | https://api.github.com/repos/simonw/datasette/issues/1376 | MDEyOklzc3VlQ29tbWVudDg2MDIzMDY2Mw== | simonw 9599 | 2021-06-13T15:39:37Z | 2021-06-13T15:39:37Z | OWNER | Actually it looks like there is a PR open already that addresses this: #1296 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Official Datasette Docker image should use SQLite >= 3.31.0 (for generated columns) 919822817 | |
861087949 | https://github.com/simonw/datasette/issues/1377#issuecomment-861087949 | https://api.github.com/repos/simonw/datasette/issues/1377 | MDEyOklzc3VlQ29tbWVudDg2MTA4Nzk0OQ== | simonw 9599 | 2021-06-15T00:49:19Z | 2021-06-15T00:49:19Z | OWNER | The new `skip_if_scope` mechanism in `asgi-csrf` https://github.com/simonw/asgi-csrf/issues/20 is designed to help here. Now I need to design a plugin hook that allows plugins to have an opinion on whether a specific `scope` should have CSRF skipped. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Mechanism for plugins to exclude certain paths from CSRF checks 920884085 | |
861089794 | https://github.com/simonw/datasette/issues/1377#issuecomment-861089794 | https://api.github.com/repos/simonw/datasette/issues/1377 | MDEyOklzc3VlQ29tbWVudDg2MTA4OTc5NA== | simonw 9599 | 2021-06-15T00:53:29Z | 2021-06-15T00:53:29Z | OWNER | Potential hook names: - `skip_csrf(scope, datasette)` - ... I can't think of any other ones I would tolerate to be honest | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Mechanism for plugins to exclude certain paths from CSRF checks 920884085 | |
867209791 | https://github.com/simonw/datasette/issues/1377#issuecomment-867209791 | https://api.github.com/repos/simonw/datasette/issues/1377 | MDEyOklzc3VlQ29tbWVudDg2NzIwOTc5MQ== | simonw 9599 | 2021-06-23T22:51:32Z | 2021-06-23T22:51:32Z | OWNER | Documentation: https://docs.datasette.io/en/latest/plugin_hooks.html#skip-csrf-datasette-scope | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Mechanism for plugins to exclude certain paths from CSRF checks 920884085 | |
863230355 | https://github.com/simonw/datasette/pull/1378#issuecomment-863230355 | https://api.github.com/repos/simonw/datasette/issues/1378 | MDEyOklzc3VlQ29tbWVudDg2MzIzMDM1NQ== | codecov[bot] 22429695 | 2021-06-17T13:16:17Z | 2021-06-17T13:16:17Z | NONE | # [Codecov](https://codecov.io/gh/simonw/datasette/pull/1378?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report > Merging [#1378](https://codecov.io/gh/simonw/datasette/pull/1378?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (0c132d1) into [main](https://codecov.io/gh/simonw/datasette/commit/83e9c8bc7585dcc62f200e37c2daefcd669ee05e?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (83e9c8b) will **not change** coverage. > The diff coverage is `n/a`. [![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/1378/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/1378?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) ```diff @@ Coverage Diff @@ ## main #1378 +/- ## ======================================= Coverage 91.68% 91.68% ======================================= Files 34 34 Lines 4340 4340 ======================================= Hits 3979 3979 Misses 361 361 ``` ------ [Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/1378?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). > **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) > `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data` > Powered by [Codecov](https://codecov… | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Update pytest-xdist requirement from <2.3,>=2.2.1 to >=2.2.1,<2.4 923910375 | |
350521806 | https://github.com/simonw/datasette/issues/138#issuecomment-350521806 | https://api.github.com/repos/simonw/datasette/issues/138 | MDEyOklzc3VlQ29tbWVudDM1MDUyMTgwNg== | simonw 9599 | 2017-12-10T03:08:26Z | 2017-12-10T03:08:36Z | OWNER | Implemented this in 80bf3afa43e3cb396c7a7c9b168eedbc6fe0fa15 and #165. Didn't use data package though. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Per-database and per-table metadata, probably using data-package 275476839 | |
953334718 | https://github.com/simonw/datasette/issues/1380#issuecomment-953334718 | https://api.github.com/repos/simonw/datasette/issues/1380 | IC_kwDOBm6k_c440ru- | glasnt 813732 | 2021-10-27T21:45:04Z | 2021-10-27T21:45:04Z | CONTRIBUTOR | I am also getting this issue, using the currently most recent version of datasette ``` $ datasette --version datasette, version 0.59.1 ``` If I run `datasette` within just a folder of files, ``` $ datasette serve . ``` Adding new files while datasette is running shows no new files, and removing files causes datasette to return 500 errors. ``` home Error 500 [Errno 2] No such file or directory: 'mydatabase.db' Powered by Datasette ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve all db files in a folder 924748955 | |
953366110 | https://github.com/simonw/datasette/issues/1380#issuecomment-953366110 | https://api.github.com/repos/simonw/datasette/issues/1380 | IC_kwDOBm6k_c440zZe | glasnt 813732 | 2021-10-27T22:48:55Z | 2021-10-27T22:48:55Z | CONTRIBUTOR | It looks like if the files argument is a directory, `config_dir` is set, but files in that folder are only loaded into `self.files` at the `Datasette` class initialisation. I tried seeing if I could get `--reload` to work, but I'm getting issues trying to use that command when specifying a directory, as the command `serve` ends up in the files list(?): ``` datasette serve . --reload Error: Invalid value for '[FILES]...': Path 'serve' does not exist. ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve all db files in a folder 924748955 | |
967181828 | https://github.com/simonw/datasette/issues/1380#issuecomment-967181828 | https://api.github.com/repos/simonw/datasette/issues/1380 | IC_kwDOBm6k_c45pgYE | Segerberg 7094907 | 2021-11-12T15:00:18Z | 2021-11-12T20:02:29Z | NONE | There is no such option see https://github.com/simonw/datasette/issues/43. But you could write a plugin using the datasette.add_database(db, name=None) https://docs.datasette.io/en/stable/internals.html#add-database-db-name-none | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve all db files in a folder 924748955 | |
967747190 | https://github.com/simonw/datasette/issues/1380#issuecomment-967747190 | https://api.github.com/repos/simonw/datasette/issues/1380 | IC_kwDOBm6k_c45rqZ2 | glasnt 813732 | 2021-11-13T00:47:26Z | 2021-11-13T00:47:26Z | CONTRIBUTOR | Would it make sense to run datasette with a fswatch/inotifywait on a folder, then? | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve all db files in a folder 924748955 | |
967801997 | https://github.com/simonw/datasette/issues/1380#issuecomment-967801997 | https://api.github.com/repos/simonw/datasette/issues/1380 | IC_kwDOBm6k_c45r3yN | Segerberg 7094907 | 2021-11-13T08:05:37Z | 2021-11-13T08:09:11Z | NONE | @glasnt yeah I guess that could be an option. I run datasette on large databases > 75gb and the startup time is a bit slow for me even with -i --inspect-file options. Here's a quick sketch for a plugin that will reload db's in a folder that you set for the plugin in metadata.json. If you request /-reload-db new db's will be added. (You probably want to implement some authentication for this =) ) https://gist.github.com/Segerberg/b96a0e0a5389dce2396497323cda7042 | {"total_count": 1, "+1": 0, "-1": 0, "laugh": 0, "hooray": 1, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve all db files in a folder 924748955 | |
864480051 | https://github.com/simonw/datasette/issues/1382#issuecomment-864480051 | https://api.github.com/repos/simonw/datasette/issues/1382 | MDEyOklzc3VlQ29tbWVudDg2NDQ4MDA1MQ== | simonw 9599 | 2021-06-20T00:20:06Z | 2021-06-20T00:21:02Z | OWNER | Yes you can - thanks for pointing this out, I've added a comment to the `install.sh` script in the `datasette-csvs` Glitch project: ```bash pip3 install -U --no-cache-dir -r requirements.txt --user && \ mkdir -p .data && \ rm .data/data.db || true && \ for f in *.csv do # Add --encoding=latin-1 to the following if your CSVs use a different encoding: sqlite-utils insert .data/data.db ${f%.*} $f --csv done ``` So if you edit that file in your own project and change the line to this: sqlite-utils insert .data/data.db ${f%.*} $f --csv --encoding=iso-8859-1 It should fix this for you. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Datasette with Glitch - is it possible to use CSV with ISO-8859-1 encoding? 925406964 | |
869069655 | https://github.com/simonw/datasette/issues/1384#issuecomment-869069655 | https://api.github.com/repos/simonw/datasette/issues/1384 | MDEyOklzc3VlQ29tbWVudDg2OTA2OTY1NQ== | simonw 9599 | 2021-06-26T22:36:14Z | 2021-06-26T22:37:37Z | OWNER | Documentation for the new hook is now live at https://docs.datasette.io/en/latest/plugin_hooks.html#get-metadata-datasette-key-database-table-fallback Link to the current snapshot of that documentation: https://github.com/simonw/datasette/blob/05a312caf3debb51aa1069939923a49e21cd2bd1/docs/plugin_hooks.rst#get-metadata-datasette-key-database-table-fallback | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
869069768 | https://github.com/simonw/datasette/issues/1384#issuecomment-869069768 | https://api.github.com/repos/simonw/datasette/issues/1384 | MDEyOklzc3VlQ29tbWVudDg2OTA2OTc2OA== | simonw 9599 | 2021-06-26T22:37:53Z | 2021-06-26T22:37:53Z | OWNER | The documentation doesn't describe the ``fallback`` argument at the moment. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
869069926 | https://github.com/simonw/datasette/issues/1384#issuecomment-869069926 | https://api.github.com/repos/simonw/datasette/issues/1384 | MDEyOklzc3VlQ29tbWVudDg2OTA2OTkyNg== | simonw 9599 | 2021-06-26T22:40:15Z | 2021-06-26T22:40:53Z | OWNER | The documentation says: > **datasette**: You can use this to access plugin configuration options via `datasette.plugin_config(your_plugin_name)`, or to execute SQL queries. That's not accurate: since the plugin hook is a regular function, not an awaitable, you can't use it to run `await db.execute(...)` so you can't execute SQL queries. I can fix this with the await-me-maybe pattern, used for other plugin hooks: https://simonwillison.net/2020/Sep/2/await-me-maybe/ BUT... that requires changing the `ds.metadata()` function to be awaitable, which will affect every existing plugn that uses that documented internal method! | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
869070076 | https://github.com/simonw/datasette/issues/1384#issuecomment-869070076 | https://api.github.com/repos/simonw/datasette/issues/1384 | MDEyOklzc3VlQ29tbWVudDg2OTA3MDA3Ng== | simonw 9599 | 2021-06-26T22:42:21Z | 2021-06-26T22:42:21Z | OWNER | Hmmm... that's tricky, since one of the most obvious ways to use this hook is to load metadata from database tables using SQL queries. @brandonrobertz do you have a working example of using this hook to populate metadata from database tables I can try? | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
869070348 | https://github.com/simonw/datasette/issues/1384#issuecomment-869070348 | https://api.github.com/repos/simonw/datasette/issues/1384 | MDEyOklzc3VlQ29tbWVudDg2OTA3MDM0OA== | simonw 9599 | 2021-06-26T22:46:18Z | 2021-06-26T22:46:18Z | OWNER | Here's where the plugin hook is called, demonstrating the `fallback=` argument: https://github.com/simonw/datasette/blob/05a312caf3debb51aa1069939923a49e21cd2bd1/datasette/app.py#L426-L472 I'm not convinced of the use-case for passing `fallback=` to the hook here - is there a reason a plugin might care whether fallback is `True` or `False`, seeing as the `metadata()` method already respects that fallback logic on line 459? | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
869070941 | https://github.com/simonw/datasette/issues/1384#issuecomment-869070941 | https://api.github.com/repos/simonw/datasette/issues/1384 | MDEyOklzc3VlQ29tbWVudDg2OTA3MDk0MQ== | simonw 9599 | 2021-06-26T22:53:34Z | 2021-06-26T22:53:34Z | OWNER | The `await` thing is worrying me a lot - it feels like this plugin hook is massively less useful if it can't make it's own DB queries and generally do asynchronous stuff - but I'd also like not to break every existing plugin that calls `datasette.metadata(...)`. One solution that could work: introduce a new method, maybe `await datasette.get_metadata(...)`, which uses this plugin hook - and keep the existing `datasette.metadata()` method (which doesn't call the hook) around. This would ensure existing plugins keep on working. Then, upgrade those plugins separately - with the goal of deprecating and removing `.metadata()` entirely in Datasette 1.0 - having upgraded the plugins in the meantime. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
869071167 | https://github.com/simonw/datasette/issues/1384#issuecomment-869071167 | https://api.github.com/repos/simonw/datasette/issues/1384 | MDEyOklzc3VlQ29tbWVudDg2OTA3MTE2Nw== | simonw 9599 | 2021-06-26T22:55:36Z | 2021-06-26T22:55:36Z | OWNER | Just realized I already have an issue open for this, at #860. I'm going to close that and continue work on this in this issue. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
869071435 | https://github.com/simonw/datasette/issues/1384#issuecomment-869071435 | https://api.github.com/repos/simonw/datasette/issues/1384 | MDEyOklzc3VlQ29tbWVudDg2OTA3MTQzNQ== | simonw 9599 | 2021-06-26T22:59:26Z | 2021-06-26T22:59:26Z | OWNER | The other alternative is to finish the work to build a `_metadata` internal table, see #1168. The idea there was that if we want to support efficient pagination and search across the metadata for thousands of attached tables powering it with a plugin hook doesn't work well - we don't want to call the hook once for every one of 1,000+ tables just to implement the homepage. So instead, all metadata for all attached databases would be loaded into an in-memory database called `_metadata`. Plugins that want to modify stored metadata could then do so by directly writing to that table. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
869071790 | https://github.com/simonw/datasette/issues/1384#issuecomment-869071790 | https://api.github.com/repos/simonw/datasette/issues/1384 | MDEyOklzc3VlQ29tbWVudDg2OTA3MTc5MA== | simonw 9599 | 2021-06-26T23:04:12Z | 2021-06-26T23:04:12Z | OWNER | > Hmmm... that's tricky, since one of the most obvious ways to use this hook is to load metadata from database tables using SQL queries. > > @brandonrobertz do you have a working example of using this hook to populate metadata from database tables I can try? Answering my own question: here's how Brandon implements it in his `datasette-live-config` plugin: https://github.com/next-LI/datasette-live-config/blob/72e335e887f1c69c54c6c2441e07148955b0fc9f/datasette_live_config/__init__.py#L50-L160 That's using a completely separate SQLite connection (actually wrapped in `sqlite-utils`) and making blocking synchronous calls to it. This is a pragmatic solution, which works - and likely performs just fine, because SQL queries like this against a small database are so fast that not running them asynchronously isn't actually a problem. But... it's weird. Everywhere else in Datasette land uses `await db.execute(...)` - but here's an example where users are encouraged to use blocking calls instead. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
869074182 | https://github.com/simonw/datasette/issues/1384#issuecomment-869074182 | https://api.github.com/repos/simonw/datasette/issues/1384 | MDEyOklzc3VlQ29tbWVudDg2OTA3NDE4Mg== | brandonrobertz 2670795 | 2021-06-26T23:37:42Z | 2021-06-26T23:37:42Z | CONTRIBUTOR | > > Hmmm... that's tricky, since one of the most obvious ways to use this hook is to load metadata from database tables using SQL queries. > > @brandonrobertz do you have a working example of using this hook to populate metadata from database tables I can try? > > Answering my own question: here's how Brandon implements it in his `datasette-live-config` plugin: https://github.com/next-LI/datasette-live-config/blob/72e335e887f1c69c54c6c2441e07148955b0fc9f/datasette_live_config/__init__.py#L50-L160 > > That's using a completely separate SQLite connection (actually wrapped in `sqlite-utils`) and making blocking synchronous calls to it. > > This is a pragmatic solution, which works - and likely performs just fine, because SQL queries like this against a small database are so fast that not running them asynchronously isn't actually a problem. > > But... it's weird. Everywhere else in Datasette land uses `await db.execute(...)` - but here's an example where users are encouraged to use blocking calls instead. _Ideally_ this hook would be asynchronous, but when I started down that path I quickly realized how large of a change this would be, since metadata gets used synchronously across the entire Datasette codebase. (And calling async code from sync is non-trivial.) In my live-configuration implementation I use synchronous reads using a persistent sqlite connection. This works pretty well in practice, but I agree it's limiting. My thinking around this was to go with the path of least change as `Datasette.metadata()` is a critical core function. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
869074701 | https://github.com/simonw/datasette/issues/1384#issuecomment-869074701 | https://api.github.com/repos/simonw/datasette/issues/1384 | MDEyOklzc3VlQ29tbWVudDg2OTA3NDcwMQ== | brandonrobertz 2670795 | 2021-06-26T23:45:18Z | 2021-06-26T23:45:37Z | CONTRIBUTOR | > Here's where the plugin hook is called, demonstrating the `fallback=` argument: > > https://github.com/simonw/datasette/blob/05a312caf3debb51aa1069939923a49e21cd2bd1/datasette/app.py#L426-L472 > > I'm not convinced of the use-case for passing `fallback=` to the hook here - is there a reason a plugin might care whether fallback is `True` or `False`, seeing as the `metadata()` method already respects that fallback logic on line 459? I think you're right. I can't think of a reason why the plugin would care about the `fallback` parameter since plugins are currently mandated to return a full, global metadata dict. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
869075368 | https://github.com/simonw/datasette/issues/1384#issuecomment-869075368 | https://api.github.com/repos/simonw/datasette/issues/1384 | MDEyOklzc3VlQ29tbWVudDg2OTA3NTM2OA== | simonw 9599 | 2021-06-26T23:53:55Z | 2021-06-26T23:53:55Z | OWNER | Great, let's drop fallback then. My instinct at the moment is to ship this plugin hook as-is but with a warning that it may change before Datasette 1.0 - then before 1.0 either figure out an async variant or finish the database-backed metadata concept from #1168 and recommend that as an alternative. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
869075395 | https://github.com/simonw/datasette/issues/1384#issuecomment-869075395 | https://api.github.com/repos/simonw/datasette/issues/1384 | MDEyOklzc3VlQ29tbWVudDg2OTA3NTM5NQ== | simonw 9599 | 2021-06-26T23:54:21Z | 2021-06-26T23:59:21Z | OWNER | (It may well be that implementing #1168 involves a switch to async metadata) | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
1062124485 | https://github.com/simonw/datasette/issues/1384#issuecomment-1062124485 | https://api.github.com/repos/simonw/datasette/issues/1384 | IC_kwDOBm6k_c4_TrvF | khusmann 167160 | 2022-03-08T19:26:32Z | 2022-03-08T19:26:32Z | NONE | Looks like I'm late to the party here, but wanted to join the convo if there's still time before this interface is solidified in v1.0. My plugin use case is for education / social science data, which is meta-data heavy in the documentation of measurement scales, instruments, collection procedures, etc. that I want to connect to columns, tables, and dbs (and render in static pages, but looks like I can do that with the jinja plugin hook). I'm still digging in and I think @brandonrobertz 's approach will work for me at least for now, but I want to bump this thread in the meantime -- are there still plans for an async metadata hook at some point in the future? (or are you considering other directions?) | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
1065929510 | https://github.com/simonw/datasette/issues/1384#issuecomment-1065929510 | https://api.github.com/repos/simonw/datasette/issues/1384 | IC_kwDOBm6k_c4_iMsm | khusmann 167160 | 2022-03-12T17:49:59Z | 2022-03-12T17:49:59Z | NONE | Ok, I'm taking a slightly different approach, which I think is sort of close to the in-memory _metadata table idea. I'm using a startup hook to load metadata / other info from the database, which I store in the datasette object for later: ``` @hookimpl def startup(datasette): async def inner(): datasette._mypluginmetadata = # await db query return inner ``` Then, I can use this in other plugins: ``` @hookimpl def render_cell(value, column, table, database, datasette): # use datasette._mypluginmetadata ``` For my app I don't need anything to update dynamically so it's fine to pre-populate everything on startup. It's also good to have things precached especially for a hook like render_cell, which would otherwise require a ton of redundant db queries. Makes me wonder if we could take a sort of similar caching approach with the internal _metadata table. Like have a little watchdog that could query all of the attached dbs for their _metadata tables every 5min or so, which then could be merged into the in memory _metadata table which then could be accessed sync by the plugins, or something like that. For most the use cases I can think of, live updates don't need to take into effect immediately; refreshing a cache every 5min or on some other trigger (adjustable w a config setting) would be just fine. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
1065940779 | https://github.com/simonw/datasette/issues/1384#issuecomment-1065940779 | https://api.github.com/repos/simonw/datasette/issues/1384 | IC_kwDOBm6k_c4_iPcr | brandonrobertz 2670795 | 2022-03-12T18:49:29Z | 2022-03-12T18:50:07Z | CONTRIBUTOR | Hello! Just wanted to chime in and note that there's a plugin to have Datasette [watch for updates to an external metadata.yaml/json and update the internal settings accordingly](https://datasette.io/plugins/datasette-remote-metadata), so I think the cache/poll use case is already covered. @khusmann If you don't need truly dynamic metadata then what you've come up with or the plugin ought to work fine. Making the get_metadata async won't improve the situation by itself as only some of the code paths accessing metadata use that hook. The other paths use the internal metadata dict. Trying to force all paths through a async hook would have performance ramifications and making everything use the internal meta will cause problems for users that need changes to take effect immediately. This is why I came to the non-async solution as it was the path of least change within Datasette. As always, open to new ideas, etc! | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
1065951744 | https://github.com/simonw/datasette/issues/1384#issuecomment-1065951744 | https://api.github.com/repos/simonw/datasette/issues/1384 | IC_kwDOBm6k_c4_iSIA | khusmann 167160 | 2022-03-12T19:47:17Z | 2022-03-12T19:47:17Z | NONE | Awesome, thanks @brandonrobertz ! The plugin is close, but looks like it only grabs remote metadata, is that right? Instead what I'm wanting is to grab metadata embedded in the attached databases. Rather than extending that plugin, at this point I've realized I need a lot more flexibility in metadata for my data model (esp around formatting cell values and custom file exports) so rather than extending that I'll continue working on a plugin specific to my app. If I'm understanding your plugin code correctly, you query the db using the sync handle every time `get_metdata` is called, right? Won't this become a pretty big bottleneck if a hook into `render_cell` is trying to read metadata / plugin config? > Making the get_metadata async won't improve the situation by itself as only some of the code paths accessing metadata use that hook. The other paths use the internal metadata dict. I agree -- because things like `render_cell` will potentially want to read metadata/config, `get_metadata` should really remain sync and lightweight, which we can do with something like the remote-metadata plugin that could also poll metadata tables in attached databases. That leaves your app, where it sounds like you want changes made by the user in the browser in to be immediately reflected, rather than have to wait for the next metadata refresh. In this case I wonder if you could have your app make a sync write to the datasette object so the change would have the immediate effect, but then have a separate async polling mechanism to eventually write that change out to the database for long-term persistence. Then you'd have the best of both worlds, I think? But probably not worth the trouble if your use cases are small (and/or you're not reading metadata/config from tight loops like render_cell). | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
1066006292 | https://github.com/simonw/datasette/issues/1384#issuecomment-1066006292 | https://api.github.com/repos/simonw/datasette/issues/1384 | IC_kwDOBm6k_c4_ifcU | brandonrobertz 2670795 | 2022-03-13T02:09:44Z | 2022-03-13T02:09:44Z | CONTRIBUTOR | > If I'm understanding your plugin code correctly, you query the db using the sync handle every time `get_metdata` is called, right? Won't this become a pretty big bottleneck if a hook into `render_cell` is trying to read metadata / plugin config? Reading from sqlite DBs is pretty quick and I didn't notice significant performance issues when I was benchmarking. I tested on very large Datasette deployments (hundreds of DBs, millions of rows). See ["Many small queries are efficient in sqlite"](https://sqlite.org/np1queryprob.html) for more information on the rationale here. Also note that in the [datasette-live-config](https://github.com/next-LI/datasette-live-config) reference plugin, the DB connection is cached, so that eliminated most of the performance worries we had. If you need to ensure fresh metadata is being read inside of a `render_cell` hook specifically, you don't need to do anything further! `get_metadata` gets called before `render_cell` every request, so it already has access to the synced meta. There shouldn't be a need to call `get_metadata(...)` or `metadata(...)` inside `render_cell`, you can just use `datasette._metadata_local` if you're really worried about performance. > The plugin is close, but looks like it only grabs remote metadata, is that right? Instead what I'm wanting is to grab metadata embedded in the attached databases. Yes correct, the datadette-remote-metadata plugin doesn't do that. But the datasette-live-config plugin does. [It supports a `__metadata` table](https://github.com/next-LI/datasette-live-config/blob/main/datasette_live_config/__init__.py#L107-L138) that, when it exists on an attached DB, gets pulled into the Datasette internal `_metadata` and is also accessible via `get_metadata`. Updating is instantaneous so there's no gotchas for users or security issues for users relying on the metadata-based permissions. Simon talked about eventually making something like this a standard feature of Datasette, but I'm not sure what the status is on that! Good luck! | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
1066143991 | https://github.com/simonw/datasette/issues/1384#issuecomment-1066143991 | https://api.github.com/repos/simonw/datasette/issues/1384 | IC_kwDOBm6k_c4_jBD3 | khusmann 167160 | 2022-03-13T17:13:09Z | 2022-03-13T17:13:09Z | NONE | Thanks for taking the time to reply @brandonrobertz , this is really helpful info. > See "Many small queries are efficient in sqlite" for more information on the rationale here. Also note that in the datasette-live-config reference plugin, the DB connection is cached, so that eliminated most of the performance worries we had. Ah, that's nifty! Yeah, then caching on the python side is likely a waste :) I'm new to working with sqlite so this is super good to know the many-small-queries is a common pattern > I tested on very large Datasette deployments (hundreds of DBs, millions of rows). For my reference, did you include a `render_cell` plugin calling `get_metadata` in those tests? I'm less concerned now that I know a little more about sqlite's caching, but that special situation will jump you to a few orders of magnitude above what the sqlite article describes (e.g. 200 vs 20,000 queries+metadata merges for a page displaying 100 rows of a 200 column table). It wouldn't scale with db size as much as # of visible cells being rendered on the page, although they would be identical queries I suppose so will cache well. (If you didn't test this specific situation, no worries -- I'm just trying to calibrate my intuition on this and can do my own benchmarks at some point.) > Simon talked about eventually making something like this a standard feature of Datasette Yeah, getting metadata (and static pages as well for that matter) from internal tables definitely has my vote for including as a standard feature! Its really nice to be able to distribute a single *.db with all the metadata and static pages bundled. My metadata are sufficiently complex/domain specific that it makes sense to continue on my own plugin for now, but I'll be thinking about more general parts I can spin off as possible contributions to liveconfig (if you're open to them) or other plugins in this ecosystem. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
1066169718 | https://github.com/simonw/datasette/issues/1384#issuecomment-1066169718 | https://api.github.com/repos/simonw/datasette/issues/1384 | IC_kwDOBm6k_c4_jHV2 | brandonrobertz 2670795 | 2022-03-13T19:48:49Z | 2022-03-13T19:48:49Z | CONTRIBUTOR | > For my reference, did you include a `render_cell` plugin calling `get_metadata` in those tests? You shouldn't need to do this, as I mentioned previously. The code inside `render_cell` hook already has access to the most recently sync'd metadata via `datasette._metadata_local`. Refreshing the metadata for every cell seems ... excessive. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
1066194130 | https://github.com/simonw/datasette/issues/1384#issuecomment-1066194130 | https://api.github.com/repos/simonw/datasette/issues/1384 | IC_kwDOBm6k_c4_jNTS | khusmann 167160 | 2022-03-13T22:23:04Z | 2022-03-13T22:23:04Z | NONE | Ah, sorry, I didn't get what you were saying you the first time. Using _metadata_local in that way makes total sense -- I agree, refreshing metadata each cell was seeming quite excessive. Now I'm on the same page! :) | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
1066222323 | https://github.com/simonw/datasette/issues/1384#issuecomment-1066222323 | https://api.github.com/repos/simonw/datasette/issues/1384 | IC_kwDOBm6k_c4_jULz | brandonrobertz 2670795 | 2022-03-14T00:36:42Z | 2022-03-14T00:36:42Z | CONTRIBUTOR | > Ah, sorry, I didn't get what you were saying you the first time. Using _metadata_local in that way makes total sense -- I agree, refreshing metadata each cell was seeming quite excessive. Now I'm on the same page! :) All good. Report back any issues you find with this stuff. Metadata/dynamic config hasn't been tested widely outside of what I've done AFAIK. If you find a strong use case for async meta, it's going to be better to know sooner rather than later! | {"total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Plugin hook for dynamic metadata 930807135 | |
869105782 | https://github.com/simonw/datasette/pull/1385#issuecomment-869105782 | https://api.github.com/repos/simonw/datasette/issues/1385 | MDEyOklzc3VlQ29tbWVudDg2OTEwNTc4Mg== | codecov[bot] 22429695 | 2021-06-27T05:48:55Z | 2021-09-13T17:29:30Z | NONE | # [Codecov](https://codecov.io/gh/simonw/datasette/pull/1385?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report > Merging [#1385](https://codecov.io/gh/simonw/datasette/pull/1385?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (db78094) into [main](https://codecov.io/gh/simonw/datasette/commit/ea627baccf980d7d8ebc9e1ffff1fe34d556e56f?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (ea627ba) will **not change** coverage. > The diff coverage is `n/a`. > :exclamation: Current head db78094 differs from pull request most recent head 8d78c8c. Consider uploading reports for the commit 8d78c8c to get more accurate results [![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/1385/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/1385?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) ```diff @@ Coverage Diff @@ ## main #1385 +/- ## ======================================= Coverage 91.70% 91.70% ======================================= Files 34 34 Lines 4364 4364 ======================================= Hits 4002 4002 Misses 362 362 ``` ------ [Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/1385?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). > **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comme… | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Fix + improve get_metadata plugin hook docs 930855052 | |
869677851 | https://github.com/simonw/datasette/pull/1386#issuecomment-869677851 | https://api.github.com/repos/simonw/datasette/issues/1386 | MDEyOklzc3VlQ29tbWVudDg2OTY3Nzg1MQ== | codecov[bot] 22429695 | 2021-06-28T13:18:50Z | 2021-06-28T13:18:50Z | NONE | # [Codecov](https://codecov.io/gh/simonw/datasette/pull/1386?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report > Merging [#1386](https://codecov.io/gh/simonw/datasette/pull/1386?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (e974ed1) into [main](https://codecov.io/gh/simonw/datasette/commit/ea627baccf980d7d8ebc9e1ffff1fe34d556e56f?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (ea627ba) will **not change** coverage. > The diff coverage is `n/a`. [![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/1386/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/1386?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) ```diff @@ Coverage Diff @@ ## main #1386 +/- ## ======================================= Coverage 91.70% 91.70% ======================================= Files 34 34 Lines 4364 4364 ======================================= Hits 4002 4002 Misses 362 362 ``` ------ [Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/1386?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). > **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) > `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data` > Powered by [Codecov](https://codecov… | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Update asgiref requirement from <3.4.0,>=3.2.10 to >=3.2.10,<3.5.0 931557895 | |
873134866 | https://github.com/simonw/datasette/issues/1387#issuecomment-873134866 | https://api.github.com/repos/simonw/datasette/issues/1387 | MDEyOklzc3VlQ29tbWVudDg3MzEzNDg2Ng== | simonw 9599 | 2021-07-02T16:58:52Z | 2021-07-02T16:58:52Z | OWNER | What's weird here is that the URL itself is correct - it starts with `/collection-analysis/` as expected - but the hostname is wrong. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | absolute_url() behind a proxy assembles incorrect http://127.0.0.1:8001/ URLs 935930820 | |
873136440 | https://github.com/simonw/datasette/issues/1387#issuecomment-873136440 | https://api.github.com/repos/simonw/datasette/issues/1387 | MDEyOklzc3VlQ29tbWVudDg3MzEzNjQ0MA== | simonw 9599 | 2021-07-02T17:01:48Z | 2021-07-02T17:01:48Z | OWNER | Here's what's happening: https://github.com/simonw/datasette/blob/d23a2671386187f61872b9f6b58e0f80ac61f8fe/datasette/views/table.py#L827-L829 This is being run through `absolute_url()` - defined here: https://github.com/simonw/datasette/blob/d23a2671386187f61872b9f6b58e0f80ac61f8fe/datasette/app.py#L633-L637 That's because the `next_url` in the JSON needs to be a full URL that a client can retrieve - as opposed to the other links on that page which are all relative links that start with `/`: https://github.com/simonw/datasette/blob/ea627baccf980d7d8ebc9e1ffff1fe34d556e56f/datasette/templates/_table.html#L11-L15 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | absolute_url() behind a proxy assembles incorrect http://127.0.0.1:8001/ URLs 935930820 | |
873137935 | https://github.com/simonw/datasette/issues/1387#issuecomment-873137935 | https://api.github.com/repos/simonw/datasette/issues/1387 | MDEyOklzc3VlQ29tbWVudDg3MzEzNzkzNQ== | simonw 9599 | 2021-07-02T17:03:36Z | 2021-07-02T17:03:36Z | OWNER | And the links to apply a facet value are broken too! https://ilsweb.cincinnatilibrary.org/collection-analysis/current_collection-3d4a4b7/bib?_facet=bib_level_callnumber ```json { "value": "g l fiction", "label": "g l fiction", "count": 212, "toggle_url": "https://127.0.0.1:8010/collection-analysis/current_collection-3d4a4b7/bib.json?_facet=bib_level_callnumber&bib_level_callnumber=g+l+fiction", "selected": false } ``` Same problem: https://github.com/simonw/datasette/blob/ea627baccf980d7d8ebc9e1ffff1fe34d556e56f/datasette/facets.py#L251-L261 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | absolute_url() behind a proxy assembles incorrect http://127.0.0.1:8001/ URLs 935930820 | |
873139138 | https://github.com/simonw/datasette/issues/1387#issuecomment-873139138 | https://api.github.com/repos/simonw/datasette/issues/1387 | MDEyOklzc3VlQ29tbWVudDg3MzEzOTEzOA== | simonw 9599 | 2021-07-02T17:05:47Z | 2021-07-02T17:05:47Z | OWNER | In this case the proxy is Apache. So there are a couple of potential fixes: - Configure Apache to pass the original HTTP request `Host:` header through to the proxied application. This should then be documented. - Add a new optional feature to Datasette called something like `base_host` which, if set, is always used in place of the host in `request.url` when constructing new URLs. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | absolute_url() behind a proxy assembles incorrect http://127.0.0.1:8001/ URLs 935930820 | |
873140742 | https://github.com/simonw/datasette/issues/1387#issuecomment-873140742 | https://api.github.com/repos/simonw/datasette/issues/1387 | MDEyOklzc3VlQ29tbWVudDg3MzE0MDc0Mg== | simonw 9599 | 2021-07-02T17:08:40Z | 2021-07-02T17:08:40Z | OWNER | `ProxyPreserveHost On` is the Apache setting - it defaults to `Off`: https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypreservehost | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | absolute_url() behind a proxy assembles incorrect http://127.0.0.1:8001/ URLs 935930820 | |
873141222 | https://github.com/simonw/datasette/issues/1387#issuecomment-873141222 | https://api.github.com/repos/simonw/datasette/issues/1387 | MDEyOklzc3VlQ29tbWVudDg3MzE0MTIyMg== | simonw 9599 | 2021-07-02T17:09:32Z | 2021-07-02T17:09:32Z | OWNER | I'm going to add this to the suggested Apache configuration at https://docs.datasette.io/en/stable/deploying.html#apache-proxy-configuration | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | absolute_url() behind a proxy assembles incorrect http://127.0.0.1:8001/ URLs 935930820 | |
873156408 | https://github.com/simonw/datasette/issues/1387#issuecomment-873156408 | https://api.github.com/repos/simonw/datasette/issues/1387 | MDEyOklzc3VlQ29tbWVudDg3MzE1NjQwOA== | simonw 9599 | 2021-07-02T17:37:30Z | 2021-07-02T17:37:30Z | OWNER | Updated documentation is here: https://docs.datasette.io/en/latest/deploying.html#apache-proxy-configuration | {"total_count": 1, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 1, "rocket": 0, "eyes": 0} | absolute_url() behind a proxy assembles incorrect http://127.0.0.1:8001/ URLs 935930820 | |
873166836 | https://github.com/simonw/datasette/issues/1387#issuecomment-873166836 | https://api.github.com/repos/simonw/datasette/issues/1387 | MDEyOklzc3VlQ29tbWVudDg3MzE2NjgzNg== | rayvoelker 9308268 | 2021-07-02T17:58:23Z | 2021-07-02T17:58:23Z | NONE | Thanks Simon for nailing that one down! It does seem a little confusing that the ProxyPreservehost option is set to Off By default, but this config totally did the trick and fixed the issue ``` <Location /collection-analysis/> ProxyPass http://127.0.0.1:8010/collection-analysis/ ProxyPreservehost On </Location> ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | absolute_url() behind a proxy assembles incorrect http://127.0.0.1:8001/ URLs 935930820 | |
875738149 | https://github.com/simonw/datasette/issues/1388#issuecomment-875738149 | https://api.github.com/repos/simonw/datasette/issues/1388 | MDEyOklzc3VlQ29tbWVudDg3NTczODE0OQ== | simonw 9599 | 2021-07-07T16:14:29Z | 2021-07-07T16:14:29Z | OWNER | This sounds like a valuable feature for people running Datasette behind a proxy. | {"total_count": 2, "+1": 2, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve using UNIX domain socket 939051549 | |
875740085 | https://github.com/simonw/datasette/issues/1388#issuecomment-875740085 | https://api.github.com/repos/simonw/datasette/issues/1388 | MDEyOklzc3VlQ29tbWVudDg3NTc0MDA4NQ== | simonw 9599 | 2021-07-07T16:17:08Z | 2021-07-07T16:17:08Z | OWNER | Looks pretty easy to implement - here's a hint from Uvicorn source code: https://github.com/encode/uvicorn/blob/b5af1049e63c059dc750a450c807b9768f91e906/uvicorn/main.py#L368 Need to work out a simple pattern for testing this too. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve using UNIX domain socket 939051549 | |
875741410 | https://github.com/simonw/datasette/issues/1388#issuecomment-875741410 | https://api.github.com/repos/simonw/datasette/issues/1388 | MDEyOklzc3VlQ29tbWVudDg3NTc0MTQxMA== | simonw 9599 | 2021-07-07T16:18:50Z | 2021-07-07T16:18:50Z | OWNER | You could actually run Datasette like this today without modifications by running a thin Python script that imports from `datasette.app`, instantiates the ASGI app and passes that to `uvicorn.run` - but I like this as a supported feature too. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve using UNIX domain socket 939051549 | |
875742910 | https://github.com/simonw/datasette/issues/1388#issuecomment-875742910 | https://api.github.com/repos/simonw/datasette/issues/1388 | MDEyOklzc3VlQ29tbWVudDg3NTc0MjkxMA== | simonw 9599 | 2021-07-07T16:20:50Z | 2021-07-07T16:23:02Z | OWNER | I wonder if `--fd` is worth supporting too? Uvicorn documentation says that's useful for running under process managers, I'd want to understand exactly how to use that (and test it) before adding the feature though. https://www.uvicorn.org/settings/ Docs on how to use a process manager: https://www.uvicorn.org/deployment/#supervisor | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve using UNIX domain socket 939051549 | |
876213177 | https://github.com/simonw/datasette/issues/1388#issuecomment-876213177 | https://api.github.com/repos/simonw/datasette/issues/1388 | MDEyOklzc3VlQ29tbWVudDg3NjIxMzE3Nw== | aslakr 80737 | 2021-07-08T07:47:17Z | 2021-07-08T07:47:17Z | CONTRIBUTOR | > This sounds like a valuable feature for people running Datasette behind a proxy. Yes, in some cases it is easer to use e.g. Apache's [ProxyPass Directive](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass) with Unix Domain Socket like `unix:/home/www.socket|http://localhost/whatever/`. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve using UNIX domain socket 939051549 | |
877714698 | https://github.com/simonw/datasette/issues/1388#issuecomment-877714698 | https://api.github.com/repos/simonw/datasette/issues/1388 | MDEyOklzc3VlQ29tbWVudDg3NzcxNDY5OA== | simonw 9599 | 2021-07-10T23:01:37Z | 2021-07-10T23:01:37Z | OWNER | Can test this with: ``` curl --unix-socket ${socket} -i "http://localhost/" ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve using UNIX domain socket 939051549 | |
877715654 | https://github.com/simonw/datasette/issues/1388#issuecomment-877715654 | https://api.github.com/repos/simonw/datasette/issues/1388 | MDEyOklzc3VlQ29tbWVudDg3NzcxNTY1NA== | simonw 9599 | 2021-07-10T23:15:06Z | 2021-07-10T23:15:06Z | OWNER | I can run tests against it using `httpx`: https://www.python-httpx.org/advanced/#usage_1 > ```pycon > >>> import httpx > >>> # Connect to the Docker API via a Unix Socket. > >>> transport = httpx.HTTPTransport(uds="/var/run/docker.sock") > >>> client = httpx.Client(transport=transport) > >>> response = client.get("http://docker/info") > ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve using UNIX domain socket 939051549 | |
877716156 | https://github.com/simonw/datasette/issues/1388#issuecomment-877716156 | https://api.github.com/repos/simonw/datasette/issues/1388 | MDEyOklzc3VlQ29tbWVudDg3NzcxNjE1Ng== | simonw 9599 | 2021-07-10T23:22:21Z | 2021-07-10T23:22:21Z | OWNER | I don't have the Datasette test suite running on Windows yet, but I'd like it to run there some day - so ideally this test would be skipped if Unix domain sockets are not supported by the underlying operating system. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve using UNIX domain socket 939051549 | |
877716359 | https://github.com/simonw/datasette/issues/1388#issuecomment-877716359 | https://api.github.com/repos/simonw/datasette/issues/1388 | MDEyOklzc3VlQ29tbWVudDg3NzcxNjM1OQ== | simonw 9599 | 2021-07-10T23:24:58Z | 2021-07-10T23:24:58Z | OWNER | Apparently Windows 10 has Unix domain socket support: https://bugs.python.org/issue33408 > Unix socket (AF_UNIX) is now avalible in Windows 10 (April 2018 Update). Please add Python support for it. > More details about it on https://blogs.msdn.microsoft.com/commandline/2017/12/19/af_unix-comes-to-windows/ But it's not clear if this is going to work. That same issue thread (the issue is still open) suggests using `hasattr(socket, 'AF_UNIX'))` to detect support in tests. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve using UNIX domain socket 939051549 | |
877716993 | https://github.com/simonw/datasette/issues/1388#issuecomment-877716993 | https://api.github.com/repos/simonw/datasette/issues/1388 | MDEyOklzc3VlQ29tbWVudDg3NzcxNjk5Mw== | simonw 9599 | 2021-07-10T23:34:02Z | 2021-07-10T23:34:02Z | OWNER | Figured out an example nginx configuration. This in `nginx.conf`: daemon off; events { worker_connections 1024; } http { server { listen 8092; location / { proxy_pass http://datasette; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } upstream datasette { server unix:/tmp/datasette.sock; } } Then run `datasette --uds /tmp/datasette.sock` Then run nginx like this: nginx -c ./nginx.conf Then hits to `http://localhost:8092/` will be proxied to Datasette. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve using UNIX domain socket 939051549 | |
877717262 | https://github.com/simonw/datasette/issues/1388#issuecomment-877717262 | https://api.github.com/repos/simonw/datasette/issues/1388 | MDEyOklzc3VlQ29tbWVudDg3NzcxNzI2Mg== | simonw 9599 | 2021-07-10T23:37:54Z | 2021-07-10T23:37:54Z | OWNER | > I wonder if `--fd` is worth supporting too? I'm going to hold off on implementing this until someone asks for it. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve using UNIX domain socket 939051549 | |
877721003 | https://github.com/simonw/datasette/issues/1388#issuecomment-877721003 | https://api.github.com/repos/simonw/datasette/issues/1388 | MDEyOklzc3VlQ29tbWVudDg3NzcyMTAwMw== | simonw 9599 | 2021-07-11T00:21:19Z | 2021-07-11T00:21:19Z | OWNER | Documentation: https://docs.datasette.io/en/latest/deploying.html#nginx-proxy-configuration | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve using UNIX domain socket 939051549 | |
877725193 | https://github.com/simonw/datasette/issues/1388#issuecomment-877725193 | https://api.github.com/repos/simonw/datasette/issues/1388 | MDEyOklzc3VlQ29tbWVudDg3NzcyNTE5Mw== | simonw 9599 | 2021-07-11T01:18:38Z | 2021-07-11T01:18:38Z | OWNER | Wrote up a TIL: https://til.simonwillison.net/nginx/proxy-domain-sockets | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Serve using UNIX domain socket 939051549 | |
876618582 | https://github.com/simonw/datasette/issues/1389#issuecomment-876618582 | https://api.github.com/repos/simonw/datasette/issues/1389 | MDEyOklzc3VlQ29tbWVudDg3NjYxODU4Mg== | simonw 9599 | 2021-07-08T17:32:40Z | 2021-07-08T17:32:40Z | OWNER | This makes sense to me since other useful querystring arguments like this can be set as defaults in the `metadata.json` configuration. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | "searchmode": "raw" in table metadata 940077168 | |
876618847 | https://github.com/simonw/datasette/issues/1389#issuecomment-876618847 | https://api.github.com/repos/simonw/datasette/issues/1389 | MDEyOklzc3VlQ29tbWVudDg3NjYxODg0Nw== | simonw 9599 | 2021-07-08T17:33:08Z | 2021-07-08T17:33:08Z | OWNER | Relevant documentation: https://docs.datasette.io/en/0.57.1/full_text_search.html#advanced-sqlite-search-queries | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | "searchmode": "raw" in table metadata 940077168 | |
876619271 | https://github.com/simonw/datasette/issues/1389#issuecomment-876619271 | https://api.github.com/repos/simonw/datasette/issues/1389 | MDEyOklzc3VlQ29tbWVudDg3NjYxOTI3MQ== | simonw 9599 | 2021-07-08T17:33:49Z | 2021-07-08T17:33:49Z | OWNER | Relevant code: https://github.com/simonw/datasette/blob/d23a2671386187f61872b9f6b58e0f80ac61f8fe/datasette/views/table.py#L491-L498 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | "searchmode": "raw" in table metadata 940077168 | |
876619531 | https://github.com/simonw/datasette/issues/1389#issuecomment-876619531 | https://api.github.com/repos/simonw/datasette/issues/1389 | MDEyOklzc3VlQ29tbWVudDg3NjYxOTUzMQ== | simonw 9599 | 2021-07-08T17:34:16Z | 2021-07-08T17:34:16Z | OWNER | If I implement this I'll also set it up so `?_searchmode=default` can be used to over-ride that and go back to the default behaviour. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | "searchmode": "raw" in table metadata 940077168 | |
876620095 | https://github.com/simonw/datasette/issues/1389#issuecomment-876620095 | https://api.github.com/repos/simonw/datasette/issues/1389 | MDEyOklzc3VlQ29tbWVudDg3NjYyMDA5NQ== | simonw 9599 | 2021-07-08T17:35:09Z | 2021-07-08T17:35:09Z | OWNER | Also came up here: https://github.com/simonw/datasette/issues/268#issuecomment-876616414 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | "searchmode": "raw" in table metadata 940077168 | |
877681031 | https://github.com/simonw/datasette/issues/1389#issuecomment-877681031 | https://api.github.com/repos/simonw/datasette/issues/1389 | MDEyOklzc3VlQ29tbWVudDg3NzY4MTAzMQ== | simonw 9599 | 2021-07-10T18:17:29Z | 2021-07-10T18:17:29Z | OWNER | I don't like `?_searchmode=default` because it suggests "use the default" - but it actually over-rides the default that was specified by `"searchmode": "raw"` in `metadata.json`. I'm going with `?_searchmode=escaped` instead. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | "searchmode": "raw" in table metadata 940077168 | |
381455054 | https://github.com/simonw/datasette/issues/139#issuecomment-381455054 | https://api.github.com/repos/simonw/datasette/issues/139 | MDEyOklzc3VlQ29tbWVudDM4MTQ1NTA1NA== | simonw 9599 | 2018-04-16T01:24:13Z | 2018-04-16T01:24:13Z | OWNER | I think Vega-Lite is the way to go here: https://vega.github.io/vega-lite/ I've been playing around with it and Datasette with some really positive initial results: https://vega.github.io/editor/#/gist/vega-lite/simonw/89100ce80573d062d70f780d10e5e609/decada131575825875c0a076e418c661c2adb014/vice-shootings-gender-race-by-department.vl.json https://vega.github.io/editor/#/gist/vega-lite/simonw/5f69fbe29380b0d5d95f31a385f49ee4/7087b64df03cf9dba44a5258a606f29182cb8619/trees-san-francisco.vl.json | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Build a visualization plugin for Vega 275493851 | |
403909389 | https://github.com/simonw/datasette/issues/139#issuecomment-403909389 | https://api.github.com/repos/simonw/datasette/issues/139 | MDEyOklzc3VlQ29tbWVudDQwMzkwOTM4OQ== | simonw 9599 | 2018-07-10T17:48:18Z | 2018-07-10T17:48:18Z | OWNER | This is done! https://github.com/simonw/datasette-vega | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Build a visualization plugin for Vega 275493851 | |
877308310 | https://github.com/simonw/datasette/issues/1390#issuecomment-877308310 | https://api.github.com/repos/simonw/datasette/issues/1390 | MDEyOklzc3VlQ29tbWVudDg3NzMwODMxMA== | simonw 9599 | 2021-07-09T16:29:48Z | 2021-07-09T16:29:48Z | OWNER | sudo systemctl restart datasette.service | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Mention restarting systemd in documentation 940891698 | |
877310125 | https://github.com/simonw/datasette/issues/1390#issuecomment-877310125 | https://api.github.com/repos/simonw/datasette/issues/1390 | MDEyOklzc3VlQ29tbWVudDg3NzMxMDEyNQ== | simonw 9599 | 2021-07-09T16:32:57Z | 2021-07-09T16:32:57Z | OWNER | https://docs.datasette.io/en/latest/deploying.html#running-datasette-using-systemd | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Mention restarting systemd in documentation 940891698 | |
877682533 | https://github.com/simonw/datasette/issues/1391#issuecomment-877682533 | https://api.github.com/repos/simonw/datasette/issues/1391 | MDEyOklzc3VlQ29tbWVudDg3NzY4MjUzMw== | simonw 9599 | 2021-07-10T18:28:05Z | 2021-07-10T18:28:05Z | OWNER | Here's the test in question: https://github.com/simonw/datasette/blob/a6c55afe8c82ead8deb32f90c9324022fd422324/tests/test_api.py#L2033-L2046 Various other places in the test code also need changing - anything that calls `supports_generated_columns()`. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Stop using generated columns in fixtures.db 941300946 | |
877686784 | https://github.com/simonw/datasette/issues/1391#issuecomment-877686784 | https://api.github.com/repos/simonw/datasette/issues/1391 | MDEyOklzc3VlQ29tbWVudDg3NzY4Njc4NA== | simonw 9599 | 2021-07-10T18:56:03Z | 2021-07-10T18:56:03Z | OWNER | Here's the SQL used to generate the table for the test: https://github.com/simonw/datasette/blob/02b19c7a9afd328f22040ab33b5c1911cd904c7c/tests/fixtures.py#L723-L733 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Stop using generated columns in fixtures.db 941300946 | |
877687196 | https://github.com/simonw/datasette/issues/1391#issuecomment-877687196 | https://api.github.com/repos/simonw/datasette/issues/1391 | MDEyOklzc3VlQ29tbWVudDg3NzY4NzE5Ng== | simonw 9599 | 2021-07-10T18:58:40Z | 2021-07-10T18:58:40Z | OWNER | I can use the `extra_databases` mechanism as demonstrated here: https://github.com/simonw/datasette/blob/9552414e1f968c6fc704031cec349c05e6bc2371/tests/test_canned_queries.py#L8-L12 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Stop using generated columns in fixtures.db 941300946 | |
877691427 | https://github.com/simonw/datasette/issues/1391#issuecomment-877691427 | https://api.github.com/repos/simonw/datasette/issues/1391 | MDEyOklzc3VlQ29tbWVudDg3NzY5MTQyNw== | simonw 9599 | 2021-07-10T19:26:00Z | 2021-07-10T19:26:00Z | OWNER | I had to run the tests locally on my macOS laptop using `pysqlite3` to get a version that supported generated columns - wrote up a TIL about that here: https://til.simonwillison.net/sqlite/pysqlite3-on-macos | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Stop using generated columns in fixtures.db 941300946 | |
877691558 | https://github.com/simonw/datasette/issues/1391#issuecomment-877691558 | https://api.github.com/repos/simonw/datasette/issues/1391 | MDEyOklzc3VlQ29tbWVudDg3NzY5MTU1OA== | simonw 9599 | 2021-07-10T19:26:57Z | 2021-07-10T19:26:57Z | OWNER | The `https://latest.datasette.io/fixtures.db` file no longer includes generated columns, which will help avoid confusion such as seen in #1376. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Stop using generated columns in fixtures.db 941300946 | |
879277953 | https://github.com/simonw/datasette/pull/1392#issuecomment-879277953 | https://api.github.com/repos/simonw/datasette/issues/1392 | MDEyOklzc3VlQ29tbWVudDg3OTI3Nzk1Mw== | simonw 9599 | 2021-07-13T17:42:31Z | 2021-07-13T17:42:31Z | OWNER | Thanks! | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Update deploying.rst 941403676 | |
879309636 | https://github.com/simonw/datasette/pull/1393#issuecomment-879309636 | https://api.github.com/repos/simonw/datasette/issues/1393 | MDEyOklzc3VlQ29tbWVudDg3OTMwOTYzNg== | simonw 9599 | 2021-07-13T18:32:25Z | 2021-07-13T18:32:25Z | OWNER | Thanks | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Update deploying.rst 941412189 | |
880278256 | https://github.com/simonw/datasette/issues/1394#issuecomment-880278256 | https://api.github.com/repos/simonw/datasette/issues/1394 | MDEyOklzc3VlQ29tbWVudDg4MDI3ODI1Ng== | simonw 9599 | 2021-07-14T23:35:18Z | 2021-07-14T23:35:18Z | OWNER | The challenge here is that faceting doesn't currently modify the inner SQL at all - it wraps it so that it can work against any SQL statement (though Datasette itself does not yet take advantage of that ability, only offering faceting on table pages). So just removing the order by wouldn't be appropriate if the inner query looked something like this: ```sql select * from items order by created desc limit 100 ``` Since the intent there would be to return facet counts against only the most recent 100 items. In SQLite the `limit` has to come after the `order by` though, so the fix here could be as easy as using a regular expression to identify queries that end with `order by COLUMN (desc)?` and stripping off that clause. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Big performance boost on faceting: skip the inner order by 944870799 | |
880287483 | https://github.com/simonw/datasette/issues/1394#issuecomment-880287483 | https://api.github.com/repos/simonw/datasette/issues/1394 | MDEyOklzc3VlQ29tbWVudDg4MDI4NzQ4Mw== | simonw 9599 | 2021-07-15T00:01:47Z | 2021-07-15T00:01:47Z | OWNER | I wrote this code: ```python _order_by_re = re.compile(r"(^.*) order by [a-zA-Z_][a-zA-Z0-9_]+( desc)?$", re.DOTALL) _order_by_braces_re = re.compile(r"(^.*) order by \[[^\]]+\]( desc)?$", re.DOTALL) def strip_order_by(sql): for regex in (_order_by_re, _order_by_braces_re): match = regex.match(sql) if match is not None: return match.group(1) return sql @pytest.mark.parametrize( "sql,expected", [ ("blah", "blah"), ("select * from foo", "select * from foo"), ("select * from foo order by bah", "select * from foo"), ("select * from foo order by bah desc", "select * from foo"), ("select * from foo order by [select]", "select * from foo"), ("select * from foo order by [select] desc", "select * from foo"), ], ) def test_strip_order_by(sql, expected): assert strip_order_by(sql) == expected ``` But it turns out I don't need it! The SQL that is passed to the facet class is created by this code: https://github.com/simonw/datasette/blob/ba11ef27edd6981eeb26d7ecf5aa236707f5f8ce/datasette/views/table.py#L677-L684 And the only place that uses that `sql_no_limit` variable is here: https://github.com/simonw/datasette/blob/ba11ef27edd6981eeb26d7ecf5aa236707f5f8ce/datasette/views/table.py#L733-L745 So I can change that to `sql_no_limit_no_order` and fix the bug that way instead. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Big performance boost on faceting: skip the inner order by 944870799 | |
880900534 | https://github.com/simonw/datasette/issues/1394#issuecomment-880900534 | https://api.github.com/repos/simonw/datasette/issues/1394 | MDEyOklzc3VlQ29tbWVudDg4MDkwMDUzNA== | simonw 9599 | 2021-07-15T17:58:03Z | 2021-07-15T17:58:03Z | OWNER | Started a conversation about this on the SQLite forum: https://sqlite.org/forum/forumpost/2d76f2bcf65d256a?t=h | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Big performance boost on faceting: skip the inner order by 944870799 | |
881129149 | https://github.com/simonw/datasette/issues/1394#issuecomment-881129149 | https://api.github.com/repos/simonw/datasette/issues/1394 | IC_kwDOBm6k_c40hPa9 | simonw 9599 | 2021-07-16T02:23:32Z | 2021-07-16T02:23:32Z | OWNER | Wrote about this in the annotated release notes for 0.58: https://simonwillison.net/2021/Jul/16/datasette-058/ | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Big performance boost on faceting: skip the inner order by 944870799 | |
880324637 | https://github.com/simonw/datasette/issues/1396#issuecomment-880324637 | https://api.github.com/repos/simonw/datasette/issues/1396 | MDEyOklzc3VlQ29tbWVudDg4MDMyNDYzNw== | simonw 9599 | 2021-07-15T01:46:26Z | 2021-07-15T01:46:26Z | OWNER | I manually published the Docker image using https://github.com/simonw/datasette/actions/workflows/push_docker_tag.yml https://github.com/simonw/datasette/runs/3072505126 The 0.58 release shows up on https://hub.docker.com/r/datasetteproject/datasette/tags?page=1&ordering=last_updated now - BUT the `latest` tag still points to a version from a month ago. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | "invalid reference format" publishing Docker image 944903881 | |
880325004 | https://github.com/simonw/datasette/issues/1396#issuecomment-880325004 | https://api.github.com/repos/simonw/datasette/issues/1396 | MDEyOklzc3VlQ29tbWVudDg4MDMyNTAwNA== | simonw 9599 | 2021-07-15T01:47:17Z | 2021-07-15T01:47:17Z | OWNER | This is the part of the publish workflow that failed and threw the "invalid reference format" error: https://github.com/simonw/datasette/blob/084cfe1e00e1a4c0515390a513aca286eeea20c2/.github/workflows/publish.yml#L100-L119 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | "invalid reference format" publishing Docker image 944903881 | |
880325362 | https://github.com/simonw/datasette/issues/1396#issuecomment-880325362 | https://api.github.com/repos/simonw/datasette/issues/1396 | MDEyOklzc3VlQ29tbWVudDg4MDMyNTM2Mg== | simonw 9599 | 2021-07-15T01:48:11Z | 2021-07-15T01:48:11Z | OWNER | In particular these three lines: https://github.com/simonw/datasette/blob/084cfe1e00e1a4c0515390a513aca286eeea20c2/.github/workflows/publish.yml#L117-L119 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | "invalid reference format" publishing Docker image 944903881 | |
880326049 | https://github.com/simonw/datasette/issues/1396#issuecomment-880326049 | https://api.github.com/repos/simonw/datasette/issues/1396 | MDEyOklzc3VlQ29tbWVudDg4MDMyNjA0OQ== | simonw 9599 | 2021-07-15T01:50:05Z | 2021-07-15T01:50:05Z | OWNER | I think I made a mistake in this commit: https://github.com/simonw/datasette/commit/0486303b60ce2784fd2e2ecdbecf304b7d6e6659 <img width="770" alt="Explicitly_push_version_tag__refs__1281_·_simonw_datasette_0486303" src="https://user-images.githubusercontent.com/9599/125715241-dc96d147-191a-4a69-bdf0-1cb092d97330.png"> It looks like I copied `$VERSION_TAG` from here - but it's not available in the `publish.yml` flow: https://github.com/simonw/datasette/blob/0486303b60ce2784fd2e2ecdbecf304b7d6e6659/.github/workflows/push_docker_tag.yml#L18-L25 | {"total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | "invalid reference format" publishing Docker image 944903881 | |
880372149 | https://github.com/simonw/datasette/issues/1396#issuecomment-880372149 | https://api.github.com/repos/simonw/datasette/issues/1396 | MDEyOklzc3VlQ29tbWVudDg4MDM3MjE0OQ== | simonw 9599 | 2021-07-15T03:56:49Z | 2021-07-15T03:56:49Z | OWNER | I'm going to leave this open until I next successfully publish a new version. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | "invalid reference format" publishing Docker image 944903881 | |
880374156 | https://github.com/simonw/datasette/issues/1396#issuecomment-880374156 | https://api.github.com/repos/simonw/datasette/issues/1396 | MDEyOklzc3VlQ29tbWVudDg4MDM3NDE1Ng== | simonw 9599 | 2021-07-15T04:03:18Z | 2021-07-15T04:03:18Z | OWNER | I fixed `datasette:latest` by running the following on my laptop: ``` docker pull datasetteproject/datasette:0.58 docker tag datasetteproject/datasette:0.58 datasetteproject/datasette:latest docker login -u datasetteproject -p ... docker push datasetteproject/datasette:latest ``` Confirmed on https://hub.docker.com/r/datasetteproject/datasette/tags?page=1&ordering=last_updated that `datasette:latest` and `datasette:0.58` both now have the same digest of `3b5ba478040e`. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | "invalid reference format" publishing Docker image 944903881 | |
880967052 | https://github.com/simonw/datasette/issues/1396#issuecomment-880967052 | https://api.github.com/repos/simonw/datasette/issues/1396 | MDEyOklzc3VlQ29tbWVudDg4MDk2NzA1Mg== | simonw 9599 | 2021-07-15T19:47:25Z | 2021-07-15T19:47:25Z | OWNER | Actually I'm going to close this now and re-open it if the problem occurs again in the future. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | "invalid reference format" publishing Docker image 944903881 |
Advanced export
JSON shape: default, array, newline-delimited, object
CREATE TABLE [issue_comments] ( [html_url] TEXT, [issue_url] TEXT, [id] INTEGER PRIMARY KEY, [node_id] TEXT, [user] INTEGER REFERENCES [users]([id]), [created_at] TEXT, [updated_at] TEXT, [author_association] TEXT, [body] TEXT, [reactions] TEXT, [issue] INTEGER REFERENCES [issues]([id]) , [performed_via_github_app] TEXT); CREATE INDEX [idx_issue_comments_issue] ON [issue_comments] ([issue]); CREATE INDEX [idx_issue_comments_user] ON [issue_comments] ([user]);
author_association 3 ✖