github
html_url | issue_url | id | node_id | user | created_at | updated_at | author_association | body | reactions | issue | performed_via_github_app |
---|---|---|---|---|---|---|---|---|---|---|---|
https://github.com/simonw/datasette/issues/2033#issuecomment-1457117383 | https://api.github.com/repos/simonw/datasette/issues/2033 | 1457117383 | IC_kwDOBm6k_c5W2djH | 9599 | 2023-03-06T22:28:55Z | 2023-03-06T22:28:55Z | OWNER | Documentation: https://docs.datasette.io/en/latest/plugins.html#installing-plugins | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1612296210 | |
https://github.com/simonw/datasette/pull/2031#issuecomment-1456997425 | https://api.github.com/repos/simonw/datasette/issues/2031 | 1456997425 | IC_kwDOBm6k_c5W2AQx | 9599 | 2023-03-06T21:04:27Z | 2023-03-06T21:06:34Z | OWNER | This is a very neat fix, for something I've been wanting for a while. Add a unit test for the row HTML page - I suggest against this page: https://latest.datasette.io/fixtures/foreign_key_references/1 - and I'll land this PR. You can model it on this test here: https://github.com/simonw/datasette/blob/a53b893c46453f35decc8c145c138671cee6140c/tests/test_table_html.py#L609-L632 I think adding it to `test_table_html.py` is OK, even though it's technically for the row page and not the table page. Thanks! | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1605481359 | |
https://github.com/simonw/datasette/pull/2028#issuecomment-1456925875 | https://api.github.com/repos/simonw/datasette/issues/2028 | 1456925875 | IC_kwDOBm6k_c5W1uyz | 22429695 | 2023-03-06T20:26:53Z | 2023-03-06T20:26:53Z | NONE | # [Codecov](https://codecov.io/gh/simonw/datasette/pull/2028?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report Patch and project coverage have no change. > Comparison is base [(`0b4a286`)](https://codecov.io/gh/simonw/datasette/commit/0b4a28691468b5c758df74fa1d72a823813c96bf?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.11% compared to head [(`a8dde13`)](https://codecov.io/gh/simonw/datasette/pull/2028?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.11%. <details><summary>Additional details and impacted files</summary> ```diff @@ Coverage Diff @@ ## main #2028 +/- ## ======================================= Coverage 92.11% 92.11% ======================================= Files 38 38 Lines 5555 5555 ======================================= Hits 5117 5117 Misses 438 438 ``` Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) </details> [:umbrella: View full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/2028?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). :loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+W… | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1590839187 | |
https://github.com/simonw/datasette/pull/2028#issuecomment-1456914694 | https://api.github.com/repos/simonw/datasette/issues/2028 | 1456914694 | IC_kwDOBm6k_c5W1sEG | 9599 | 2023-03-06T20:19:37Z | 2023-03-06T20:19:37Z | OWNER | Thanks! | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1590839187 | |
https://github.com/simonw/datasette/issues/1619#issuecomment-1455196849 | https://api.github.com/repos/simonw/datasette/issues/1619 | 1455196849 | IC_kwDOBm6k_c5WvIqx | 969875 | 2023-03-05T20:29:55Z | 2023-03-05T20:30:14Z | NONE | I have this same issue, which is happening with both json links and facets. It is not happening with column sort links in the gear popup menus, but it is happening with the sort arrow that results after you use one of those links. I'm using Apache as a proxy to Datasette; the relevant configs are: ``` ProxyPass /datasette/ http://127.0.0.1:8000/datasette/ nocanon ProxyPreserveHost on ``` ``` { "base_url": "/datasette/" } ``` If it would be useful to get a look at the running installation via the Web, Simon, let me know. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1121583414 | |
https://github.com/simonw/sqlite-utils/issues/433#issuecomment-1444474487 | https://api.github.com/repos/simonw/sqlite-utils/issues/433 | 1444474487 | IC_kwDOCGYnMM5WGO53 | 167893 | 2023-02-24T20:57:43Z | 2023-02-24T22:22:18Z | CONTRIBUTOR | I think I see what is happening here, although I haven't quite work out a fix yet. Usually: * `click.progressbar.render_progress()` renders the cursor invisible on each invocation (update of the bar) * When the progress bar goes out of scope, the `__exit()__` method is invoked, which calls `render_finish()` to make the cursor re-appear. (See terminal escape sequences `BEFORE_BAR` and `AFTER_BAR` in click). However the sqlite-utils `utils.file_progress` context manager wraps `click.progressbar` and yields an instance of a helper class: ``` python @contextlib.contextmanager def file_progress(file, silent=False, **kwargs): ... with click.progressbar(length=file_length, **kwargs) as bar: yield UpdateWrapper(file, bar.update) ``` The yielded `UpdateWrapper` goes out of scope quickly and `click.progressbar.__exit__()` is called. The cursor is made un-invisible. Hoewever `bar` is still live and so when the caller iterates on the yielded wrapper this invokes the bar's update method, calling `render_progress()`, each time printing the "make cursor invisible" escape code. The `progressbar.__exit__` function is not called again, so the cursor doesn't re-appear. | { "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1239034903 | |
https://github.com/simonw/datasette/issues/2030#issuecomment-1440854834 | https://api.github.com/repos/simonw/datasette/issues/2030 | 1440854834 | IC_kwDOBm6k_c5V4bMy | 19700859 | 2023-02-22T21:54:39Z | 2023-02-22T21:54:39Z | NONE | Thanks @dmick . I chose to create a firewall rule under my GCP to open the port of interest and datasette works. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1594383280 | |
https://github.com/simonw/datasette/issues/2030#issuecomment-1440814680 | https://api.github.com/repos/simonw/datasette/issues/2030 | 1440814680 | IC_kwDOBm6k_c5V4RZY | 1350673 | 2023-02-22T21:22:42Z | 2023-02-22T21:22:42Z | NONE | @gk7279, you had asked in a separate bug about how to redirect web servers in general. The datasette docs actually have pretty good information on this for both nginx and apache2: https://docs.datasette.io/en/stable/deploying.html#running-datasette-behind-a-proxy | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1594383280 | |
https://github.com/simonw/datasette/issues/2027#issuecomment-1440811364 | https://api.github.com/repos/simonw/datasette/issues/2027 | 1440811364 | IC_kwDOBm6k_c5V4Qlk | 19700859 | 2023-02-22T21:19:47Z | 2023-02-22T21:19:47Z | NONE | yes @dmick . How did you make your public IP redirect to your uvicorn server? Instead of nginx, I have apache2 on my GCP VM. Any pointers here are helpful too. Thanks. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1590183272 | |
https://github.com/simonw/datasette/issues/2027#issuecomment-1440762383 | https://api.github.com/repos/simonw/datasette/issues/2027 | 1440762383 | IC_kwDOBm6k_c5V4EoP | 1350673 | 2023-02-22T20:35:16Z | 2023-02-22T20:35:16Z | NONE | Was that query to me, @gk7279? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1590183272 | |
https://github.com/simonw/datasette/issues/2027#issuecomment-1440355080 | https://api.github.com/repos/simonw/datasette/issues/2027 | 1440355080 | IC_kwDOBm6k_c5V2hMI | 19700859 | 2023-02-22T16:26:41Z | 2023-02-22T16:26:41Z | NONE | Can you please help or share your expertise with #2030 ? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1590183272 | |
https://github.com/simonw/datasette/issues/1258#issuecomment-1437671409 | https://api.github.com/repos/simonw/datasette/issues/1258 | 1437671409 | IC_kwDOBm6k_c5VsR_x | 2670795 | 2023-02-20T23:39:58Z | 2023-02-20T23:39:58Z | CONTRIBUTOR | This is pretty annoying for FTS because sqlite throws an error instead of just doing something like returning all or no results. This makes users who are unfamiliar with SQL and Datasette think the canned query page is broken and is a frequent source of confusion. To anyone dealing with this: My solution is to modify the canned query so that it returns no results which cues people to fill in the blank parameters. So instead of `emails_fts match escape_fts(:search))` My canned queries now look like this: `emails_fts match escape_fts(iif(:search=="", "*", :search))` There are no asterisks in my data so the result is always blank. Ultimately it would be nice to be able to handle this in the metadata. Either making some named parameters required or setting some default values. | { "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
828858421 | |
https://github.com/simonw/sqlite-utils/issues/525#issuecomment-1435318713 | https://api.github.com/repos/simonw/sqlite-utils/issues/525 | 1435318713 | IC_kwDOCGYnMM5VjTm5 | 167893 | 2023-02-17T21:55:01Z | 2023-02-17T21:55:01Z | CONTRIBUTOR | Meanwhile, a cheap workaround is to invalidate the registered function cache: ``` python table.convert(...) db._registered_functions = set() table.convert(...) ``` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1575131737 | |
https://github.com/simonw/datasette/issues/1775#issuecomment-1426158181 | https://api.github.com/repos/simonw/datasette/issues/1775 | 1426158181 | IC_kwDOBm6k_c5VAXJl | 805751 | 2023-02-10T18:04:40Z | 2023-02-10T18:04:40Z | NONE | Is this where we talk about i18n of results? Or is that a separate thread. e.g. Having `country_long` show `España` in the Spanish version of the [global power plants demo site](https://global-power-plants.datasettes.com/) instead of `Spain`. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1323346408 | |
https://github.com/simonw/datasette/issues/2024#issuecomment-1426031395 | https://api.github.com/repos/simonw/datasette/issues/2024 | 1426031395 | IC_kwDOBm6k_c5U_4Mj | 9599 | 2023-02-10T16:11:53Z | 2023-02-10T16:11:53Z | OWNER | Relevant: https://til.simonwillison.net/sqlite/enabling-wal-mode | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1579973223 | |
https://github.com/simonw/datasette/issues/2023#issuecomment-1425988018 | https://api.github.com/repos/simonw/datasette/issues/2023 | 1425988018 | IC_kwDOBm6k_c5U_tmy | 80409402 | 2023-02-10T15:39:59Z | 2023-02-10T15:39:59Z | NONE | Thanks for confirming my doubts! I removed it after opening this issue, yup, then had another issue with `default_cache_ttl_hashed` which I assume was removed at the same time. Sorry for not trying that before opening the issue. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1579695809 | |
https://github.com/simonw/datasette/issues/2023#issuecomment-1425974877 | https://api.github.com/repos/simonw/datasette/issues/2023 | 1425974877 | IC_kwDOBm6k_c5U_qZd | 193185 | 2023-02-10T15:32:41Z | 2023-02-10T15:32:41Z | CONTRIBUTOR | I think this feature was removed in Datasette 0.61 and moved to a plugin. People who want hashed URLs can use the [datasette-hashed-urls](https://docs.datasette.io/en/stable/performance.html#performance-hashed-urls) plugin to achieve the same affect. It looks like you're trying to disable hashed urls, so I think you can just remove that config setting and things will work. | { "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1579695809 | |
https://github.com/simonw/datasette/issues/2022#issuecomment-1424848569 | https://api.github.com/repos/simonw/datasette/issues/2022 | 1424848569 | IC_kwDOBm6k_c5U7Xa5 | 1667631 | 2023-02-09T21:13:50Z | 2023-02-09T21:13:50Z | NONE | Nulls in primary keys, does it every time. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1578609658 | |
https://github.com/simonw/sqlite-utils/issues/525#issuecomment-1423387341 | https://api.github.com/repos/simonw/sqlite-utils/issues/525 | 1423387341 | IC_kwDOCGYnMM5U1yrN | 167893 | 2023-02-08T23:48:52Z | 2023-02-09T00:17:30Z | CONTRIBUTOR | PR below | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1575131737 | |
https://github.com/simonw/datasette/issues/262#issuecomment-1423067724 | https://api.github.com/repos/simonw/datasette/issues/262 | 1423067724 | IC_kwDOBm6k_c5U0kpM | 9599 | 2023-02-08T18:33:32Z | 2023-02-08T18:36:48Z | OWNER | Just realized that it's useful to be able to tell what parameters were used to generate a page... but reflecting things like `_next` back in the JSON is confusing in the presence of `next`. So I'm going to add an extra for that information too. Not sure what to call it though: - `params` - confusing because in the code that's usually used for params passed to SQL queries - `query_string` - wouldn't that be a string, not params as a dictionary? I'm going to experiment with a `request` extra that returns some bits of information about the request. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
323658641 | |
https://github.com/simonw/sqlite-utils/issues/524#issuecomment-1422681850 | https://api.github.com/repos/simonw/sqlite-utils/issues/524 | 1422681850 | IC_kwDOCGYnMM5UzGb6 | 21095447 | 2023-02-08T14:25:50Z | 2023-02-08T14:29:09Z | NONE | I live the patch here for others: _original code_ ```shell $ which sqlite-utils | xargs cat ``` ```python #!/usr/bin/python3 # -*- coding: utf-8 -*- import re import sys from sqlite_utils.cli import cli if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) sys.exit(cli()) ``` _patched/sqlite-utils.py_ ```python #!/usr/bin/python3 # -*- coding: utf-8 -*- import re import sys from sqlite_utils.cli import cli # New imports from unittest.mock import patch from sqlite_utils.cli import VALID_COLUMN_TYPES if __name__ == '__main__': # Choices of the option `--type` cli.commands['transform'].params[2].type.types[1].choices.append('DATETIME') # The dicts has to be extended with a new type with patch.dict('sqlite_utils.db.COLUMN_TYPE_MAPPING', {'DATETIME': 'DATETIME'}),\ patch('sqlite_utils.cli.VALID_COLUMN_TYPES', VALID_COLUMN_TYPES + ("DATETIME", )): # Command is unchanged sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) sys.exit(cli()) ``` And now it's working ```bash $ sqlite-utils schema events.sqlite cards.chunk.get CREATE TABLE "cards.chunk.get" ( [id] INTEGER PRIMARY KEY NOT NULL, [timestamp] TEXT, ) $ python patched/sqlite-utils.py transform events.sqlite cards.chunk.get --type timestamp DATETIME $ sqlite-utils schema events.sqlite cards.chunk.get CREATE TABLE "cards.chunk.get" ( [id] INTEGER PRIMARY KEY NOT NULL, [timestamp] DATETIME, ) ``` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1572766460 | |
https://github.com/simonw/datasette/pull/1999#issuecomment-1421988953 | https://api.github.com/repos/simonw/datasette/issues/1999 | 1421988953 | IC_kwDOBm6k_c5UwdRZ | 9599 | 2023-02-08T04:35:44Z | 2023-02-08T05:27:48Z | OWNER | Next step: get `?_next=...` working (it is ignored at the moment, even though the returned JSON includes the `"next"` key). Then... figure out how to render HTML and other requested formats. Then get the tests to pass! | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1551694938 | |
https://github.com/simonw/datasette/issues/2019#issuecomment-1421784930 | https://api.github.com/repos/simonw/datasette/issues/2019 | 1421784930 | IC_kwDOBm6k_c5Uvrdi | 9599 | 2023-02-08T01:28:25Z | 2023-02-08T01:40:46Z | OWNER | Rather than duplicate this rather awful hack: https://github.com/simonw/datasette/blob/0b4a28691468b5c758df74fa1d72a823813c96bf/datasette/views/table.py#L694-L714 I'm tempted to say that the code that calls the new pagination helper needs to ensure that the `sort` or `sort_desc` columns are selected. If it wants to ditch them later (e.g. because they were not included in `?_col=`) it can do that later once the results have come back. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1573424830 | |
https://github.com/simonw/datasette/issues/2019#issuecomment-1421600789 | https://api.github.com/repos/simonw/datasette/issues/2019 | 1421600789 | IC_kwDOBm6k_c5Uu-gV | 9599 | 2023-02-07T23:12:40Z | 2023-02-07T23:16:20Z | OWNER | Most complicated example of a paginated query: https://latest.datasette.io/fixtures?sql=select%0D%0A++pk1%2C%0D%0A++pk2%2C%0D%0A++content%2C%0D%0A++sortable%2C%0D%0A++sortable_with_nulls%2C%0D%0A++sortable_with_nulls_2%2C%0D%0A++text%0D%0Afrom%0D%0A++sortable%0D%0Awhere%0D%0A++(%0D%0A++++sortable_with_nulls+is+null%0D%0A++++and+(%0D%0A++++++(pk1+%3E+%3Ap0)%0D%0A++++++or+(%0D%0A++++++++pk1+%3D+%3Ap0%0D%0A++++++++and+pk2+%3E+%3Ap1%0D%0A++++++)%0D%0A++++)%0D%0A++)%0D%0Aorder+by%0D%0A++sortable_with_nulls+desc%2C%0D%0A++pk1%2C%0D%0A++pk2%0D%0Alimit%0D%0A++101&p0=h&p1=r ```sql select pk1, pk2, content, sortable, sortable_with_nulls, sortable_with_nulls_2, text from sortable where ( sortable_with_nulls is null and ( (pk1 > :p0) or ( pk1 = :p0 and pk2 > :p1 ) ) ) order by sortable_with_nulls desc, pk1, pk2 limit 101 ``` Generated by this page: https://latest.datasette.io/fixtures/sortable?_next=%24null%2Ch%2Cr&_sort_desc=sortable_with_nulls The `_next=` parameter there decodes as `$null,h,r` - and those components are tilde-encoded, so this can be distinguished from an actual `$null` value which would be represented as `~24null`. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1573424830 | |
https://github.com/simonw/sqlite-utils/issues/520#issuecomment-1421571810 | https://api.github.com/repos/simonw/sqlite-utils/issues/520 | 1421571810 | IC_kwDOCGYnMM5Uu3bi | 167893 | 2023-02-07T22:43:09Z | 2023-02-07T22:43:09Z | CONTRIBUTOR | Hey, isn't this essentially the same issue as #448 ? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1516644980 | |
https://github.com/simonw/datasette/issues/2019#issuecomment-1421274434 | https://api.github.com/repos/simonw/datasette/issues/2019 | 1421274434 | IC_kwDOBm6k_c5Utu1C | 9599 | 2023-02-07T18:42:42Z | 2023-02-07T18:42:42Z | OWNER | I'm going to build completely separate tests for this in `test_pagination.py`. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1573424830 | |
https://github.com/simonw/sqlite-utils/issues/524#issuecomment-1421177666 | https://api.github.com/repos/simonw/sqlite-utils/issues/524 | 1421177666 | IC_kwDOCGYnMM5UtXNC | 21095447 | 2023-02-07T17:39:00Z | 2023-02-07T17:39:00Z | NONE | > lets users make schema changes, so it's important to me that the tool work in a non-surprising way -- if you ask for a column of type X, you should get type X. If the column or table previously had CHECK constraints, they shouldn't be silently removed I've got your concern. Let's see if we will be replied on it and i'll close the issue some later. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1572766460 | |
https://github.com/simonw/sqlite-utils/issues/524#issuecomment-1421081939 | https://api.github.com/repos/simonw/sqlite-utils/issues/524 | 1421081939 | IC_kwDOCGYnMM5Us_1T | 193185 | 2023-02-07T16:42:25Z | 2023-02-07T16:43:42Z | NONE | Ha, yes, I might end up making something very niche. That's OK. I'm building a UI for [Datasette](https://datasette.io/) that lets users make schema changes, so it's important to me that the tool work in a non-surprising way -- if you ask for a column of type X, you should get type X. If the column or table previously had CHECK constraints, they shouldn't be silently removed. And so on. I had hoped that I could just lean on sqlite-utils, but I think it's a little too surprising. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1572766460 | |
https://github.com/simonw/sqlite-utils/issues/524#issuecomment-1421055590 | https://api.github.com/repos/simonw/sqlite-utils/issues/524 | 1421055590 | IC_kwDOCGYnMM5Us5Zm | 21095447 | 2023-02-07T16:25:31Z | 2023-02-07T16:25:31Z | NONE | > Ah, it looks like that is controlled by this dict: https://github.com/simonw/sqlite-utils/blob/main/sqlite_utils/db.py#L178 > > I suspect you could overwrite the datetime entry to achieve what you want And thank you for pointing me to it. At least, i can make a monkey patch for my need... | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1572766460 | |
https://github.com/simonw/sqlite-utils/issues/524#issuecomment-1421052195 | https://api.github.com/repos/simonw/sqlite-utils/issues/524 | 1421052195 | IC_kwDOCGYnMM5Us4kj | 21095447 | 2023-02-07T16:23:17Z | 2023-02-07T16:23:57Z | NONE | Isn't your suggestion too fundamental for the utility? The bigger flexibility, the bigger complexity. Your idea make sense defenitely, but how often do you make schema changes? And how many people could benefit from it, what do you think? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1572766460 | |
https://github.com/simonw/sqlite-utils/issues/524#issuecomment-1421033725 | https://api.github.com/repos/simonw/sqlite-utils/issues/524 | 1421033725 | IC_kwDOCGYnMM5Us0D9 | 193185 | 2023-02-07T16:12:13Z | 2023-02-07T16:12:13Z | NONE | I think the bigger issue is that `sqlite-utils` mixes mechanism (it implements the [12-step way to alter SQLite tables](https://www.sqlite.org/lang_altertable.html#otheralter)) and policy (it has an opinionated stance on what column types should be used). That might be a design choice to make it accessible to users by providing a reasonable set of defaults, but it doesn't quite fit my use case. It might make sense to extract a separate library that provides just the mechanisms, and then `sqlite-utils` would sit on top of that library with its opinionated set of policies. That would be a very big change, though. I might take a stab at extracting the library, but just for the table schema migration piece, not all the other features that `sqlite-utils` supports. I wouldn't expect `sqlite-utils` to depend on it. Part of my motivation is that I want to provide some other abilities, too, like support for CHECK constraints. I see that the issue in this repo (https://github.com/simonw/sqlite-utils/issues/358) proposes a bunch of short-hand constraints, which I wouldn't want to accidentally expose to people -- I want a layer that is a 1:1 mapping to SQLite. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1572766460 | |
https://github.com/simonw/sqlite-utils/issues/524#issuecomment-1421022917 | https://api.github.com/repos/simonw/sqlite-utils/issues/524 | 1421022917 | IC_kwDOCGYnMM5UsxbF | 21095447 | 2023-02-07T16:06:03Z | 2023-02-07T16:08:58Z | NONE | > Do you see a way to enable it without affecting existing users or bumping the major version number? I don't see a clean solution, only extending code with a side variable that tells us we want to apply advanced types instead of basic. it could be a similiar command like `tranform-v2 --type column DATETIME` or a cli option `transform --adv-type column DATETIME` along with a dict that contains the advanced types. Then with knowledge that we run an advanced command we take that dictionary somehow, we can wrap the current and new dictionaries by a superdict and work with it everywhere according to the knowledge. This way shouldn't affect users who are using the previous lib versions and it have to be merged in the next major one. But this way looks a bad design, too messy. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1572766460 | |
https://github.com/simonw/sqlite-utils/issues/524#issuecomment-1420992261 | https://api.github.com/repos/simonw/sqlite-utils/issues/524 | 1420992261 | IC_kwDOCGYnMM5Usp8F | 193185 | 2023-02-07T15:45:58Z | 2023-02-07T15:45:58Z | NONE | I'd support that, but I'm not the author of this library. One challenge is that would be a breaking change. Do you see a way to enable it without affecting existing users or bumping the major version number? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1572766460 | |
https://github.com/simonw/sqlite-utils/issues/524#issuecomment-1420966995 | https://api.github.com/repos/simonw/sqlite-utils/issues/524 | 1420966995 | IC_kwDOCGYnMM5UsjxT | 21095447 | 2023-02-07T15:29:28Z | 2023-02-07T15:29:28Z | NONE | I could, of course. Doest it worth bringing such the improvement to the library? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1572766460 | |
https://github.com/simonw/datasette/pull/564#issuecomment-1420941334 | https://api.github.com/repos/simonw/datasette/issues/564 | 1420941334 | IC_kwDOBm6k_c5UsdgW | 82988 | 2023-02-07T15:14:10Z | 2023-02-07T15:14:10Z | CONTRIBUTOR | Is this feature covered by any more recent updates to `datasette`, or via any plugins that you're aware of? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
473288428 | |
https://github.com/simonw/sqlite-utils/issues/524#issuecomment-1420809773 | https://api.github.com/repos/simonw/sqlite-utils/issues/524 | 1420809773 | IC_kwDOCGYnMM5Ur9Yt | 193185 | 2023-02-07T13:53:01Z | 2023-02-07T13:53:01Z | NONE | Ah, it looks like that is controlled by this dict: https://github.com/simonw/sqlite-utils/blob/main/sqlite_utils/db.py#L178 I suspect you could overwrite the datetime entry to achieve what you want | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1572766460 | |
https://github.com/simonw/sqlite-utils/issues/524#issuecomment-1420496447 | https://api.github.com/repos/simonw/sqlite-utils/issues/524 | 1420496447 | IC_kwDOCGYnMM5Uqw4_ | 21095447 | 2023-02-07T09:57:38Z | 2023-02-07T09:57:38Z | NONE | > That said, it looks like the check is only enforced at the CLI level. If you use the API directly, I think it'll work. It works, but a column becomes `TEXT` ```python In [1]: import sqlite_utils In [2]: db = sqlite_utils.Database('events.sqlite') In [3]: table = db['cards.chunk.get'] In [4]: table.columns_dict Out[4]: {'id': int, 'timestamp': float, 'data_chunk_number': int, 'user_id': str, 'meta_duplication_source_id': int, 'context_sort_attribute': str, 'context_sort_order': str} In [5]: from datetime import datetime In [7]: table.transform(types={'timestamp': datetime}) In [8]: table.columns_dict Out[8]: {'id': int, 'timestamp': str, 'data_chunk_number': int, 'user_id': str, 'meta_duplication_source_id': int, 'context_sort_attribute': str, 'context_sort_order': str} ``` ```bash ❯ sqlite-utils schema events.sqlite cards.chunk.get CREATE TABLE "cards.chunk.get" ( [id] INTEGER PRIMARY KEY NOT NULL, [timestamp] TEXT, ... ``` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1572766460 | |
https://github.com/simonw/datasette/issues/2019#issuecomment-1420109153 | https://api.github.com/repos/simonw/datasette/issues/2019 | 1420109153 | IC_kwDOBm6k_c5UpSVh | 9599 | 2023-02-07T02:32:36Z | 2023-02-07T02:32:36Z | OWNER | Doing this as a class makes sense to me. There are a few steps: - Instantiate the class with the information it needs, which includes sort order, page size, tiebreaker columns and SQL query and parameters - Generate the new SQL query that will actually be executed - maybe this takes the optional `_next` parameter? This returns the SQL and params that should be executed, where the SQL now includes pagination logic plus order by and limit - The calling code then gets to execute the SQL query to fetch the rows - Last step: those rows are passed to a paginator method which returns `(rows, next)` - where `rows` is the rows truncated to the correct length (really just with the last one cut off if it's too long for the length) and `next` is either `None` or a token, depending on if there should be a next page. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1573424830 | |
https://github.com/simonw/datasette/issues/2019#issuecomment-1420106315 | https://api.github.com/repos/simonw/datasette/issues/2019 | 1420106315 | IC_kwDOBm6k_c5UpRpL | 9599 | 2023-02-07T02:28:03Z | 2023-02-07T02:28:36Z | OWNER | So I think I can write an abstraction that applies keyset pagination to ANY arbitrary SQL query provided it is given the query, the existing params (so it can pick names for the new params that won't overlap with them), the desired sort order, any existing `_next` token AND the columns that should be used to tie-break any duplicates. Those tie breakers will be either the primary key(s) or `rowid` if none are provided. What about the case of SQL views, where offset/limit should be used instead? I'm inclined to have that as a separate pagination abstraction entirely, with the calling code deciding which pagination helper to use based on if keyset pagination makes sense or not. Might be easier to design a class structure for this starting with `OffsetPaginator`, then using that to inform the design of `KeysetPaginator`. Might put these in `datasette.utils.pagination` to start off with, then maybe extract them out to `sqlite-utils` later once they've proven themselves. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1573424830 | |
https://github.com/simonw/datasette/issues/2019#issuecomment-1420104254 | https://api.github.com/repos/simonw/datasette/issues/2019 | 1420104254 | IC_kwDOBm6k_c5UpRI- | 9599 | 2023-02-07T02:24:46Z | 2023-02-07T02:24:46Z | OWNER | Even more complicated: https://latest.datasette.io/fixtures/sortable?sortable_with_nulls__notnull=1&_next=0~2E692704598586882%2Ce%2Cr&_sort=sortable_with_nulls_2 The rewritten SQL for that is: ```sql select * from (select pk1, pk2, content, sortable, sortable_with_nulls, sortable_with_nulls_2, text from sortable where "sortable_with_nulls" is not null) where (sortable_with_nulls_2 > :p2 or (sortable_with_nulls_2 = :p2 and ((pk1 > :p0) or (pk1 = :p0 and pk2 > :p1)))) order by sortable_with_nulls_2, pk1, pk2 limit 101 ``` And it still has the same number of explain steps as the current SQL witohut the subselect. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1573424830 | |
https://github.com/simonw/datasette/issues/2019#issuecomment-1420101175 | https://api.github.com/repos/simonw/datasette/issues/2019 | 1420101175 | IC_kwDOBm6k_c5UpQY3 | 9599 | 2023-02-07T02:22:11Z | 2023-02-07T02:22:11Z | OWNER | A more complex example: https://latest.datasette.io/fixtures/sortable?_next=0~2E2650566289400591%2Ca%2Cu&_sort=sortable_with_nulls_2 SQL: ```sql select pk1, pk2, content, sortable, sortable_with_nulls, sortable_with_nulls_2, text from sortable where (sortable_with_nulls_2 > :p2 or (sortable_with_nulls_2 = :p2 and ((pk1 > :p0) or (pk1 = :p0 and pk2 > :p1)))) order by sortable_with_nulls_2, pk1, pk2 limit 101 ``` https://latest.datasette.io/fixtures?sql=select+pk1%2C+pk2%2C+content%2C+sortable%2C+sortable_with_nulls%2C+sortable_with_nulls_2%2C+text+from+sortable+where+%28sortable_with_nulls_2+%3E+%3Ap2+or+%28sortable_with_nulls_2+%3D+%3Ap2+and+%28%28pk1+%3E+%3Ap0%29%0A++or%0A%28pk1+%3D+%3Ap0+and+pk2+%3E+%3Ap1%29%29%29%29+order+by+sortable_with_nulls_2%2C+pk1%2C+pk2+limit+101&p0=a&p1=u&p2=0.2650566289400591 Here's the explain: 49 steps long https://latest.datasette.io/fixtures?sql=explain+select+pk1%2C+pk2%2C+content%2C+sortable%2C+sortable_with_nulls%2C+sortable_with_nulls_2%2C+text+from+sortable+where+%28sortable_with_nulls_2+%3E+%3Ap2+or+%28sortable_with_nulls_2+%3D+%3Ap2+and+%28%28pk1+%3E+%3Ap0%29%0D%0A++or%0D%0A%28pk1+%3D+%3Ap0+and+pk2+%3E+%3Ap1%29%29%29%29+order+by+sortable_with_nulls_2%2C+pk1%2C+pk2+limit+101&p2=0.2650566289400591&p0=a&p1=u Rewritten with a subselect: ```sql select * from ( select pk1, pk2, content, sortable, sortable_with_nulls, sortable_with_nulls_2, text from sortable ) where (sortable_with_nulls_2 > :p2 or (sortable_with_nulls_2 = :p2 and ((pk1 > :p0) or (pk1 = :p0 and pk2 > :p1)))) order by sortable_with_nulls_2, pk1, pk2 limit 101 ``` https://latest.datasette.io/fixtures?sql=select+*+from+(%0D%0A++select+pk1%2C+pk2%2C+content%2C+sortable%2C+sortable_with_nulls%2C+sortable_with_nulls_2%2C+text+from+sortable%0D%0A)%0D%0Awhere+(sortable_with_nulls_2+%3E+%3Ap2+or+(sortable_with_nulls_2+%3D+%3Ap2+and+((pk1+%3E+%3Ap0)%0D%0A++or%0D%0A(pk1+%3D+%3Ap0+and+pk2+%3E+%3Ap1))))+order+by+sortable_with_nulls_2%2C+pk1%2C+pk2+limit+101&p2=0.2650566289400591&p0=a&p1=u … | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1573424830 | |
https://github.com/simonw/datasette/issues/2019#issuecomment-1420094396 | https://api.github.com/repos/simonw/datasette/issues/2019 | 1420094396 | IC_kwDOBm6k_c5UpOu8 | 9599 | 2023-02-07T02:18:11Z | 2023-02-07T02:19:16Z | OWNER | For the SQL underlying this page (the second page in that compound primary key paginated sequence): https://latest.datasette.io/fixtures/compound_three_primary_keys?_next=a%2Cd%2Cv The explain for the default query: https://latest.datasette.io/fixtures?sql=explain+select%0D%0A++pk1%2C%0D%0A++pk2%2C%0D%0A++pk3%2C%0D%0A++content%0D%0Afrom%0D%0A++compound_three_primary_keys%0D%0Awhere%0D%0A++%28%0D%0A++++%28pk1+%3E+%3Ap0%29%0D%0A++++or+%28%0D%0A++++++pk1+%3D+%3Ap0%0D%0A++++++and+pk2+%3E+%3Ap1%0D%0A++++%29%0D%0A++++or+%28%0D%0A++++++pk1+%3D+%3Ap0%0D%0A++++++and+pk2+%3D+%3Ap1%0D%0A++++++and+pk3+%3E+%3Ap2%0D%0A++++%29%0D%0A++%29%0D%0Aorder+by%0D%0A++pk1%2C%0D%0A++pk2%2C%0D%0A++pk3%0D%0Alimit%0D%0A++101&p0=a&p1=d&p2=v The explain for that query rewritten as this: ```sql explain select * from ( select pk1, pk2, pk3, content from compound_three_primary_keys ) where ( (pk1 > :p0) or ( pk1 = :p0 and pk2 > :p1 ) or ( pk1 = :p0 and pk2 = :p1 and pk3 > :p2 ) ) order by pk1, pk2, pk3 limit 101 ``` https://latest.datasette.io/fixtures?sql=explain+select+*+from+%28select+%0D%0A++pk1%2C%0D%0A++pk2%2C%0D%0A++pk3%2C%0D%0A++content%0D%0Afrom%0D%0A++compound_three_primary_keys%0D%0A%29%0D%0A++where%0D%0A++%28%0D%0A++++%28pk1+%3E+%3Ap0%29%0D%0A++++or+%28%0D%0A++++++pk1+%3D+%3Ap0%0D%0A++++++and+pk2+%3E+%3Ap1%0D%0A++++%29%0D%0A++++or+%28%0D%0A++++++pk1+%3D+%3Ap0%0D%0A++++++and+pk2+%3D+%3Ap1%0D%0A++++++and+pk3+%3E+%3Ap2%0D%0A++++%29%0D%0A++%29%0D%0Aorder+by%0D%0A++pk1%2C%0D%0A++pk2%2C%0D%0A++pk3%0D%0Alimit%0D%0A++101&p0=a&p1=d&p2=v Both explains have 31 steps and look pretty much identical. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1573424830 | |
https://github.com/simonw/datasette/issues/2019#issuecomment-1420088670 | https://api.github.com/repos/simonw/datasette/issues/2019 | 1420088670 | IC_kwDOBm6k_c5UpNVe | 9599 | 2023-02-07T02:14:35Z | 2023-02-07T02:14:35Z | OWNER | Maybe the correct level of abstraction here is that pagination is something that happens to a SQL query that is defined as SQL and params, without an order by or limit. That's then wrapped in a sub-select and those things are added to it, plus the necessary `where` clauses depending on the page. Need to check that the query plan for pagination of a subquery isn't slower than the plan for pagination as it works today. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1573424830 | |
https://github.com/simonw/datasette/issues/2019#issuecomment-1419953256 | https://api.github.com/repos/simonw/datasette/issues/2019 | 1419953256 | IC_kwDOBm6k_c5UosRo | 9599 | 2023-02-06T23:42:56Z | 2023-02-06T23:43:10Z | OWNER | Relevant issue: - https://github.com/simonw/datasette/issues/1773 Explains this comment: https://github.com/simonw/datasette/blob/0b4a28691468b5c758df74fa1d72a823813c96bf/datasette/views/table.py#L697 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1573424830 | |
https://github.com/simonw/datasette/issues/2019#issuecomment-1419928455 | https://api.github.com/repos/simonw/datasette/issues/2019 | 1419928455 | IC_kwDOBm6k_c5UomOH | 9599 | 2023-02-06T23:21:50Z | 2023-02-06T23:21:50Z | OWNER | Found more logic relating to this: https://github.com/simonw/datasette/blob/0b4a28691468b5c758df74fa1d72a823813c96bf/datasette/views/table.py#L684-L732 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1573424830 | |
https://github.com/simonw/datasette/issues/2019#issuecomment-1419921228 | https://api.github.com/repos/simonw/datasette/issues/2019 | 1419921228 | IC_kwDOBm6k_c5UokdM | 9599 | 2023-02-06T23:14:15Z | 2023-02-06T23:14:15Z | OWNER | Crucial utility function: https://github.com/simonw/datasette/blob/0b4a28691468b5c758df74fa1d72a823813c96bf/datasette/utils/__init__.py#L137-L160 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1573424830 | |
https://github.com/simonw/datasette/issues/2019#issuecomment-1419917661 | https://api.github.com/repos/simonw/datasette/issues/2019 | 1419917661 | IC_kwDOBm6k_c5Uojld | 9599 | 2023-02-06T23:10:51Z | 2023-02-06T23:10:51Z | OWNER | I should turn `sort` and `sort_desc` into an object representing the sort order earlier in the code. I should also create something that bundles together `pks` and `use_rowid` and maybe `is_view` as well. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1573424830 | |
https://github.com/simonw/datasette/issues/2019#issuecomment-1419916684 | https://api.github.com/repos/simonw/datasette/issues/2019 | 1419916684 | IC_kwDOBm6k_c5UojWM | 9599 | 2023-02-06T23:09:51Z | 2023-02-06T23:10:13Z | OWNER | The inputs and outputs for this are pretty complex. Inputs: - `?_next=` from the query string - `is_view` - is this for a table or view? If it's a view it uses offset/limit pagination - which could actually work for arbitrary queries too. Also views could have keyset pagination if they are known to be sorted by a particular column. - `sort` and `sort_desc` reflecting the current sort order - `use_rowid` for if the table is a rowid table with no primary key of its own - `pks` - the primary keys for the table - `params` - the current set of parameters, I think used just to count their length so new params can be added as `p5` etc without collisions. This could be handled with a `s0`, `s1` etc naming convention instead. Outputs: - `where_clauses` - a list of where clauses to add to the query - `params` - additional parameters to use with the query due to the new where clauses - `order_by` - the order by clause | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1573424830 | |
https://github.com/simonw/datasette/pull/1999#issuecomment-1399343659 | https://api.github.com/repos/simonw/datasette/issues/1999 | 1399343659 | IC_kwDOBm6k_c5TaEor | 9599 | 2023-01-21T22:19:20Z | 2023-02-06T23:02:12Z | OWNER | HTML mode needs a list of renderers so it can show links to `.geojson` etc - can do that as a hidden extra (maybe called `renderers`), repeating this code: https://github.com/simonw/datasette/blob/e4ebef082de90db4e1b8527abc0d582b7ae0bc9d/datasette/views/base.py#L477-L497 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1551694938 | |
https://github.com/simonw/datasette/issues/262#issuecomment-1418288327 | https://api.github.com/repos/simonw/datasette/issues/262 | 1418288327 | IC_kwDOBm6k_c5UiVzH | 9599 | 2023-02-05T22:57:58Z | 2023-02-06T23:01:15Z | OWNER | I think that does make sense: `?_extra=table` perhaps, which would add `{"table": "..."}`. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
323658641 | |
https://github.com/simonw/sqlite-utils/issues/524#issuecomment-1419734229 | https://api.github.com/repos/simonw/sqlite-utils/issues/524 | 1419734229 | IC_kwDOCGYnMM5Un2zV | 193185 | 2023-02-06T20:53:28Z | 2023-02-06T21:16:29Z | NONE | I think it's not currently possible: sqlite-utils requires that it be one of `integer`, `text`, `float`, `blob` ([see code](https://github.com/simonw/sqlite-utils/blob/fc221f9b62ed8624b1d2098e564f525c84497969/sqlite_utils/cli.py#L2266)) IMO, this is a bit of friction and it would be nice if it was more permissive. SQLite permits developers to use any data type when creating a table. For example, this is a perfectly cromulent sqlite session that creates a table with columns of type `baz` and `bar`: ``` sqlite> create table foo(column1 baz, column2 bar); sqlite> .schema foo CREATE TABLE foo(column1 baz, column2 bar); sqlite> select * from pragma_table_info('foo'); cid name type notnull dflt_value pk ---------- ---------- ---------- ---------- ---------- ---------- 0 column1 baz 0 0 1 column2 bar 0 0 ``` The idea is that the application developer will know what meaning to ascribe to those types. For example, I'm working on a plugin to Datasette. Dates are tricky to handle. If you have some existing rows, you can look at the values in them to know how a user is serializing the dates -- as an ISO 8601 string? An RFC 3339 string? With millisecond precision? With timezone offset? But if you don't yet have any rows, you have to guess. If the column is of type `TEXT`, you don't even know that it's meant to hold a date! In this case, my plugin will look to see if the column is of type `DATE` or `DATETIME`, and assume a certain representation when writing. Perhaps there is an argument that sqlite-utils is trying to conform to SQLite's strict mode, and that is why it limits the choices. In strict mode, SQLite requires that the data type be one of `INT`, `INTEGER`, `REAL`, `TEXT`, `BLOB`, `ANY`. But that can't be the case -- sqlite-utils supports `FLOAT`, which is not one of the valid types in strict mode, and it rejects `INT`, `REAL` and `ANY`, which _are_ valid. | { "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1572766460 | |
https://github.com/simonw/sqlite-utils/issues/524#issuecomment-1419740776 | https://api.github.com/repos/simonw/sqlite-utils/issues/524 | 1419740776 | IC_kwDOCGYnMM5Un4Zo | 193185 | 2023-02-06T20:59:01Z | 2023-02-06T20:59:01Z | NONE | That said, it looks like the check is only enforced at the CLI level. If you use the API directly, I think it'll work. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1572766460 | |
https://github.com/simonw/sqlite-utils/issues/524#issuecomment-1419390560 | https://api.github.com/repos/simonw/sqlite-utils/issues/524 | 1419390560 | IC_kwDOCGYnMM5Umi5g | 21095447 | 2023-02-06T16:43:47Z | 2023-02-06T16:43:47Z | NONE | > SQLite doesn't have a native `DATETIME` type. It stores dates internally as strings and then has [functions](https://www.sqlite.org/lang_datefunc.html) to work with date-like strings. Yes it's weird. That's correct. But my issue is about the application level libraries that, i suppose, have better data understanding if see a specific type such as `DATETIME`. I'm writing data with **dataset** i've mentioned. The lib changes its behavior depending on a type. I saw different behavior with types `DATETIME, FLOAT, TEXT`. Dataset, for their part, is built upon Sqlalchemy, you know what it is. To be honest, i didn't dive into the details of why the behavior changes, but when i altered manually by other util a type of column to `DATETIME` things got back to normal. On the matter, can i achieve it with Sqlite Utils at the moment? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1572766460 | |
https://github.com/simonw/sqlite-utils/issues/524#issuecomment-1419357290 | https://api.github.com/repos/simonw/sqlite-utils/issues/524 | 1419357290 | IC_kwDOCGYnMM5Umaxq | 25778 | 2023-02-06T16:21:44Z | 2023-02-06T16:21:44Z | CONTRIBUTOR | SQLite doesn't have a native `DATETIME` type. It stores dates internally as strings and then has [functions](https://www.sqlite.org/lang_datefunc.html) to work with date-like strings. Yes it's weird. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1572766460 | |
https://github.com/simonw/datasette/issues/2016#issuecomment-1418288077 | https://api.github.com/repos/simonw/datasette/issues/2016 | 1418288077 | IC_kwDOBm6k_c5UiVvN | 9599 | 2023-02-05T22:56:43Z | 2023-02-05T22:56:43Z | OWNER | This absolutely makes sense. One of the biggest goals for Datasette 1.0 is "documented template contexts" - for any default template in Datasette that people might want to over-ride there should be documentation that describes the available context variables, plus tests that ensure they don't accidentally get broken by future changes. Ensuring description/title/etc are available on the index page feels like it fits well into that bucket. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1571207083 | |
https://github.com/simonw/sqlite-utils/issues/433#issuecomment-1416486796 | https://api.github.com/repos/simonw/sqlite-utils/issues/433 | 1416486796 | IC_kwDOCGYnMM5Ubd-M | 16236421 | 2023-02-03T22:32:10Z | 2023-02-03T22:32:10Z | NONE | Came here to say that I also have this issue. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1239034903 | |
https://github.com/simonw/datasette/issues/2011#issuecomment-1410827249 | https://api.github.com/repos/simonw/datasette/issues/2011 | 1410827249 | IC_kwDOBm6k_c5UF4Px | 9599 | 2023-01-31T17:58:54Z | 2023-01-31T17:58:54Z | OWNER | I think this is the relevant code: https://github.com/simonw/datasette/blob/0b4a28691468b5c758df74fa1d72a823813c96bf/datasette/facets.py#L260-L268 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1564769997 | |
https://github.com/simonw/datasette/issues/2010#issuecomment-1409406327 | https://api.github.com/repos/simonw/datasette/issues/2010 | 1409406327 | IC_kwDOBm6k_c5UAdV3 | 9599 | 2023-01-30T21:51:58Z | 2023-01-30T21:51:58Z | OWNER | Here's a quick prototype I knocked up for this: ```diff diff --git a/datasette/static/app.css b/datasette/static/app.css index 71437bd4..d763bcff 100644 --- a/datasette/static/app.css +++ b/datasette/static/app.css @@ -695,7 +695,48 @@ p.zero-results { +/* Force table to not be like tables anymore */ +body.row table.rows-and-columns, +body.row .rows-and-columns thead, +body.row .rows-and-columns tbody, +body.row .rows-and-columns th, +body.row .rows-and-columns td, +body.row .rows-and-columns tr { + display: block; +} + +/* Hide table headers (but not display: none;, for accessibility) */ +body.row .rows-and-columns thead tr { + position: absolute; + top: -9999px; + left: -9999px; +} + +body.row .rows-and-columns tr { + border: 1px solid #ccc; + margin-bottom: 1em; + border-radius: 10px; + background-color: white; + padding: 0.2rem; +} +body.row .rows-and-columns td { + /* Behave like a "row" */ + border: none; + border-bottom: 1px solid #eee; + padding: 0; + padding-left: 10%; + padding-bottom: 0.3em; +} + +body.row .rows-and-columns td:before { + display: block; + color: black; + padding-bottom: 0.2em; + font-size: 0.8em; + font-weight: bold; + background-color: #f5f5f5; +} /* Overrides ===============================================================*/ diff --git a/datasette/templates/row.html b/datasette/templates/row.html index 1d1b0bfd..339eb643 100644 --- a/datasette/templates/row.html +++ b/datasette/templates/row.html @@ -5,6 +5,9 @@ {% block extra_head %} {{- super() -}} <style> +{% for column in columns %} +body.row .rows-and-columns td:nth-of-type({{ loop.index }}):before { content: "{{ column|escape_css_string }}"; } +{% endfor %} @media only screen and (max-width: 576px) { {% for column in columns %} .rows-and-columns td:nth-of-type({{ loop.index }}):before { content: "{{ column|escape_css_string }}"; } ``` Now the row page looks like this at all … | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1563264257 | |
https://github.com/simonw/datasette/issues/1696#issuecomment-1407767434 | https://api.github.com/repos/simonw/datasette/issues/1696 | 1407767434 | IC_kwDOBm6k_c5T6NOK | 193185 | 2023-01-29T20:56:20Z | 2023-01-29T20:56:20Z | CONTRIBUTOR | I did some horrible things in https://github.com/cldellow/datasette-ui-extras/issues/2 to enable this in my plugin -- example here: https://dux-demo.fly.dev/cooking/posts?_facet=owner_user_id&owner_user_id=67 The implementation relies on two things: - a `filters_from_request` hook that adds a good human description (unfortunately, without the benefit of the CSS styling you mention) - doing something evil to hijack the `exact` and `not` operators in the `Filters` class. We can't leave them as is, or we'll get 2 human descriptions -- the built-in Datasette one and the one from my plugin. We can't remove them, or the filters UI will stop supporting the `=` and `!=` operators This got me thinking: it'd be neat if the list of operators that the filters UI supported wasn't a closed set. A motivating example: adding a geospatial `NEAR` operator. Ideally it'd take two arguments - a target point and a radius, so you could express a filter like `find me all rows whose lat/lng are within 10km of 43.4516° N, 80.4925° W`. (Optionally, the UI could be enhanced if the geonames database was loaded and queried, so a user could say `find me all rows whose lat/lng are within 10km of Kitchener, ON`, and the city gets translated to a lat/lng for them) | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1186696202 | |
https://github.com/simonw/datasette/pull/2008#issuecomment-1407733793 | https://api.github.com/repos/simonw/datasette/issues/2008 | 1407733793 | IC_kwDOBm6k_c5T6FAh | 9599 | 2023-01-29T18:17:40Z | 2023-01-29T18:17:40Z | OWNER | > We don't have any performance tests yet - would be a useful thing to add, I've not built anything like that before (at least not in CI, I've always done as-hoc performance testing using something like Locust) so I don't have a great feel for how it could work. Had an interesting conversation about this just now: https://fedi.simonwillison.net/@simon/109773800944614366 There's a risk that different runs will return different results due to the shared resource nature of GitHub Actions runners, but a good fix for that is to run comparative tests where you run the benchmark against e.g. both `main` and the incoming PR branch and report back on any differences. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1560982210 | |
https://github.com/simonw/datasette/pull/2008#issuecomment-1407716963 | https://api.github.com/repos/simonw/datasette/issues/2008 | 1407716963 | IC_kwDOBm6k_c5T6A5j | 193185 | 2023-01-29T17:04:03Z | 2023-01-29T17:04:03Z | CONTRIBUTOR | Performance tests - I think most places don't have them as a formal gate enforced by CI. TypeScript and scalac seem to have tests that run to capture timings. The timings are included by a bot as a comment or build check, and also stored in a database so you can graph changes over time to spot regressions. Probably overkill for Datasette! Window functions - oh, good point. Looks like Ubuntu shipped JSON1 support as far back as sqlite 3.11. I'll let this PR linger until there's a way to run against different SQLite versions. For now, I'm shipping this with `datasette-ui-extras`, since I think it's OK for a plugin to enforce a higher minimum requirement. Tests - there actually did end up being test changes to capture the undercount bug of the current implementation, so the current implementation would fail against the new tests. Perhaps a non-window function version could be written that uses `random()` instead of `row_number() over ()` in order to get a unique key. It's technically not unique, but in practice, I imagine it'll work well. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1560982210 | |
https://github.com/simonw/datasette/pull/2008#issuecomment-1407568923 | https://api.github.com/repos/simonw/datasette/issues/2008 | 1407568923 | IC_kwDOBm6k_c5T5cwb | 9599 | 2023-01-29T05:47:36Z | 2023-01-29T05:47:36Z | OWNER | > I don't know how/if you do automated tests for performance, so I haven't changed any of the tests. We don't have any performance tests yet - would be a useful thing to add, I've not built anything like that before (at least not in CI, I've always done as-hoc performance testing using something like Locust) so I don't have a great feel for how it could work. I see not having to change the tests at all for this change as a really positive sign. If you find any behaviour differences between this and the previous that's a sign we should add a mother test or two specifying the behaviour we want. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1560982210 | |
https://github.com/simonw/datasette/pull/2008#issuecomment-1407567753 | https://api.github.com/repos/simonw/datasette/issues/2008 | 1407567753 | IC_kwDOBm6k_c5T5ceJ | 9599 | 2023-01-29T05:39:54Z | 2023-01-29T05:40:34Z | OWNER | I absolutely _love_ this performance boost - really nice find. One concern: this will be the first time Datasette ships a core feature that uses window functions. Window functions were added to SQLite in [version 3.25.0](https://www.sqlite.org/releaselog/3_25_0.html) on 2018-09-15 - which means it's still very common for Datasette to run on versions that don't yet support them. So I see two options: - Detect window function support and switch between the old implementation and this better, new one - Detect window functions and disable the facet-by-JSON feature entirely if they are missing I like the first option a bit better. This also leads to a tricky CI challenge: Datasette needs to be able to run its test suite against more than one SQLite version to confidently test this feature going forward. I don't yet have a good GitHub Actions recipe for this, but I _really_ need one - for `sqlite-utils` too. Might be able to use this trick for that: https://til.simonwillison.net/sqlite/ld-preload | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1560982210 | |
https://github.com/simonw/datasette/pull/2008#issuecomment-1407471459 | https://api.github.com/repos/simonw/datasette/issues/2008 | 1407471459 | IC_kwDOBm6k_c5T5E9j | 22429695 | 2023-01-28T19:40:18Z | 2023-01-29T04:55:39Z | NONE | # [Codecov](https://codecov.io/gh/simonw/datasette/pull/2008?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report Base: **92.11**% // Head: **91.78**% // Decreases project coverage by **`-0.34%`** :warning: > Coverage data is based on head [(`f529a30`)](https://codecov.io/gh/simonw/datasette/pull/2008?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) compared to base [(`e4ebef0`)](https://codecov.io/gh/simonw/datasette/commit/e4ebef082de90db4e1b8527abc0d582b7ae0bc9d?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). > Patch has no changes to coverable lines. <details><summary>Additional details and impacted files</summary> ```diff @@ Coverage Diff @@ ## main #2008 +/- ## ========================================== - Coverage 92.11% 91.78% -0.34% ========================================== Files 38 39 +1 Lines 5555 5599 +44 ========================================== + Hits 5117 5139 +22 - Misses 438 460 +22 ``` | [Impacted Files](https://codecov.io/gh/simonw/datasette/pull/2008?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | | |---|---|---| | [datasette/facets.py](https://codecov.io/gh/simonw/datasette/pull/2008?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2ZhY2V0cy5weQ==) | `91.84% <ø> (ø)` | | | [datasette/views/row.py](https://codecov.io/gh/simonw/datasette/pull/2008?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3ZpZXdzL3Jvdy5weQ==) | `87.82% <0.00%> (ø)` | | | [datasette/view… | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1560982210 | |
https://github.com/simonw/datasette/pull/2008#issuecomment-1407561308 | https://api.github.com/repos/simonw/datasette/issues/2008 | 1407561308 | IC_kwDOBm6k_c5T5a5c | 193185 | 2023-01-29T04:50:50Z | 2023-01-29T04:50:50Z | CONTRIBUTOR | I pushed a revised version which ends up being faster -- the example which currently takes 4 seconds now runs in 500ms. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1560982210 | |
https://github.com/simonw/datasette/pull/2008#issuecomment-1407558284 | https://api.github.com/repos/simonw/datasette/issues/2008 | 1407558284 | IC_kwDOBm6k_c5T5aKM | 193185 | 2023-01-29T04:23:58Z | 2023-01-29T04:24:27Z | CONTRIBUTOR | Ack, this PR is broken. I see now that the `inner.*` is necessary for ensuring the correct count in the face of rows having duplicate values in views. That fixes the overcounting, but I think can undercount when the rows have the same data, eg a view like: ```sql SELECT '["bar"]' tags UNION ALL SELECT '["bar"]' ``` will produce a count of `{"bar": 1 }`, when it should be `{"bar": 2}`. In fact, this could apply in tables without primary keys, too. If `inner` came from a base table that had a primary key or a rowid, we could use those column(s) to solve that case. I guess a general solution would be to compute a window function so we have a distinct ID for each row. Will fiddle to see if I can get that working. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1560982210 | |
https://github.com/simonw/datasette/issues/1973#issuecomment-1407523547 | https://api.github.com/repos/simonw/datasette/issues/1973 | 1407523547 | IC_kwDOBm6k_c5T5Rrb | 193185 | 2023-01-29T00:40:31Z | 2023-01-29T00:40:31Z | CONTRIBUTOR | A +1 for switching to `CustomRow`: I think you currently only get a `CustomRow` if the result set had a column that was an fkey ([this code](https://github.com/simonw/datasette/blob/3c352b7132ef09b829abb69a0da0ad00be5edef9/datasette/views/table.py#L667-L682)) Otherwise you get vanilla `sqlite3.Row`s, which will fail if you try to access `.columns` or lookup the cell by name, which surprised me recently | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1515815014 | |
https://github.com/simonw/datasette/pull/2008#issuecomment-1407470429 | https://api.github.com/repos/simonw/datasette/issues/2008 | 1407470429 | IC_kwDOBm6k_c5T5Etd | 193185 | 2023-01-28T19:34:29Z | 2023-01-28T19:34:29Z | CONTRIBUTOR | I don't know how/if you do automated tests for performance, so I haven't changed any of the tests. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1560982210 | |
https://github.com/simonw/sqlite-utils/issues/523#issuecomment-1407264466 | https://api.github.com/repos/simonw/sqlite-utils/issues/523 | 1407264466 | IC_kwDOCGYnMM5T4SbS | 536941 | 2023-01-28T02:41:14Z | 2023-01-28T02:41:14Z | CONTRIBUTOR | I also often then run another little script to cast all empty strings to null, but i save that for another issue if this gets accepted. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1560651350 | |
https://github.com/simonw/datasette/issues/2006#issuecomment-1405488884 | https://api.github.com/repos/simonw/datasette/issues/2006 | 1405488884 | IC_kwDOBm6k_c5Txg70 | 9599 | 2023-01-26T19:20:53Z | 2023-01-26T19:20:53Z | OWNER | I can run a GitHub code search a week or so before the release to give me time to get in touch with anyone who has actions that look like they might break. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1558644003 | |
https://github.com/simonw/datasette/issues/2006#issuecomment-1405488523 | https://api.github.com/repos/simonw/datasette/issues/2006 | 1405488523 | IC_kwDOBm6k_c5Txg2L | 9599 | 2023-01-26T19:20:32Z | 2023-01-26T19:20:32Z | OWNER | This won't actually help that much if the user's GitHub Actions workflow does the equivalent of this: ``` pip install datasette datasette publish cloudrun mydb.db ... ``` Since they'll get the 1.0 release too. Since they'll need to make changes anyway, maybe a better solution is to document this and tell people they should use this instead: ``` datasette publish cloudrun mydb.db ... --branch 0.64.1 ``` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1558644003 | |
https://github.com/simonw/datasette/issues/2005#issuecomment-1404458011 | https://api.github.com/repos/simonw/datasette/issues/2005 | 1404458011 | IC_kwDOBm6k_c5TtlQb | 9599 | 2023-01-26T01:41:30Z | 2023-01-26T01:41:50Z | OWNER | My code looked like this: ```python @hookimpl def extra_template_vars(datasette, view_name, database): async def inner(): if view_name == "database": return {"blah": 1} return inner ``` It returns `None` in the case where the `if` condition does not match. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1557507274 | |
https://github.com/simonw/datasette/issues/262#issuecomment-1404253358 | https://api.github.com/repos/simonw/datasette/issues/262 | 1404253358 | IC_kwDOBm6k_c5TszSu | 9599 | 2023-01-25T21:35:32Z | 2023-01-25T21:35:32Z | OWNER | This issue here would benefit from some kid of mechanism for returning just the HTML of the table itself, without any of the surrounding material. I'm not sure if that would make sense as an extra or not: - https://github.com/simonw/datasette-search-all/issues/17 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
323658641 | |
https://github.com/simonw/sqlite-utils/pull/203#issuecomment-1404070841 | https://api.github.com/repos/simonw/sqlite-utils/issues/203 | 1404070841 | IC_kwDOCGYnMM5TsGu5 | 536941 | 2023-01-25T18:47:18Z | 2023-01-25T18:47:18Z | CONTRIBUTOR | i'll adopt this PR to make the changes @simonw suggested https://github.com/simonw/sqlite-utils/pull/203#issuecomment-753567932 | { "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
743384829 | |
https://github.com/simonw/datasette/pull/2003#issuecomment-1404065571 | https://api.github.com/repos/simonw/datasette/issues/2003 | 1404065571 | IC_kwDOBm6k_c5TsFcj | 536941 | 2023-01-25T18:44:42Z | 2023-01-25T18:44:42Z | CONTRIBUTOR | see this related discussion to a change in API in sqlite-utils https://github.com/simonw/sqlite-utils/pull/203#issuecomment-753567932 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1555701851 | |
https://github.com/simonw/datasette/pull/2004#issuecomment-1403110269 | https://api.github.com/repos/simonw/datasette/issues/2004 | 1403110269 | IC_kwDOBm6k_c5TocN9 | 22429695 | 2023-01-25T05:18:54Z | 2023-01-25T05:18:54Z | NONE | # [Codecov](https://codecov.io/gh/simonw/datasette/pull/2004?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report Base: **92.11**% // Head: **92.11**% // No change to project coverage :thumbsup: > Coverage data is based on head [(`dca7634`)](https://codecov.io/gh/simonw/datasette/pull/2004?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) compared to base [(`e4ebef0`)](https://codecov.io/gh/simonw/datasette/commit/e4ebef082de90db4e1b8527abc0d582b7ae0bc9d?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). > Patch has no changes to coverable lines. <details><summary>Additional details and impacted files</summary> ```diff @@ Coverage Diff @@ ## main #2004 +/- ## ======================================= Coverage 92.11% 92.11% ======================================= Files 38 38 Lines 5555 5555 ======================================= Hits 5117 5117 Misses 438 438 ``` | [Impacted Files](https://codecov.io/gh/simonw/datasette/pull/2004?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | | |---|---|---| | [datasette/utils/\_\_init\_\_.py](https://codecov.io/gh/simonw/datasette/pull/2004?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3V0aWxzL19faW5pdF9fLnB5) | `94.86% <ø> (ø)` | | Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium… | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1556065335 | |
https://github.com/simonw/datasette/issues/2001#issuecomment-1403084856 | https://api.github.com/repos/simonw/datasette/issues/2001 | 1403084856 | IC_kwDOBm6k_c5ToWA4 | 193185 | 2023-01-25T04:31:02Z | 2023-01-25T04:31:02Z | CONTRIBUTOR | Aha, it's user error on my part. Adding ``` sqlite3_db_config.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_int, ctypes.c_int] ``` makes it work reliably both on the CLI and from datasette, and now I can reproduce the errors you mentioned in the issue description. | { "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1553615704 | |
https://github.com/simonw/datasette/issues/2001#issuecomment-1403078134 | https://api.github.com/repos/simonw/datasette/issues/2001 | 1403078134 | IC_kwDOBm6k_c5ToUX2 | 193185 | 2023-01-25T04:20:43Z | 2023-01-25T04:22:28Z | CONTRIBUTOR | I'm on Ubuntu, unfortunately. :( Would it still be relevant? I think I've narrowed things down a bit more. Even `sqlite3_free(sqlite3_malloc(128))` segfaults -- this suggests to me that it's something about the sqlite3 library that was loaded, vs, say, getting the wrong db handle when I go spelunking in the Connection object. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1553615704 | |
https://github.com/simonw/datasette/issues/2001#issuecomment-1403071122 | https://api.github.com/repos/simonw/datasette/issues/2001 | 1403071122 | IC_kwDOBm6k_c5ToSqS | 406380 | 2023-01-25T04:12:41Z | 2023-01-25T04:12:41Z | NONE | @cldellow glad to hear you tried it, as I got grossed out by my own suggestion ;) If you are on macOS I do have one trick for debugging segfaults using lldb. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1553615704 | |
https://github.com/simonw/datasette/issues/2001#issuecomment-1403053144 | https://api.github.com/repos/simonw/datasette/issues/2001 | 1403053144 | IC_kwDOBm6k_c5ToORY | 193185 | 2023-01-25T03:34:53Z | 2023-01-25T03:34:53Z | CONTRIBUTOR | Your comment introduced me to this issue in sqlite and to the `ctypes` module - thanks! > I also hope that the datasette developers will enable this mode in a test environment [...] > perhaps we could figure out how to invoke it using `ctypes` I'm not a Datasette developer, but I _am_ curious to learn more about getting unholy access to the sqlite C APIs inside of Datasette. (Such access could also help #1293, and if done without grovelling inside of pysqlite's Connection object for the db handle, could even be relatively safe.) I experimented a bit. I came up with https://gist.github.com/cldellow/85bba507c314b127f85563869cd94820 If you run `python3 enable-strict-quoting-sqlite3.py`, it seems to set those flags correctly -- `SELECT "foo"` fails where it would normally succeed. But if you put it in a `plugins/` dir and run `datasette --plugins-dir plugins/`, it segfaults when it tries to call `sqlite3_db_config` on the connections created by Datasette. I am... confused. I'm _pretty_ sure I'm using the same python and the same libsqlite3 in both scenarios, so I would expect it to work. @gwk do you know anything that might help me debug the segfault? I gather that my approach of going grovelling inside of a `PyObject` is particularly dangerous, but I was thinking (a) it's necessary in order to test Datasette's use of the sqlite3 library and (b) even if it's not portable, it'd be good enough for running the tests on a single machine. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1553615704 | |
https://github.com/simonw/datasette/issues/1099#issuecomment-1402900354 | https://api.github.com/repos/simonw/datasette/issues/1099 | 1402900354 | IC_kwDOBm6k_c5Tno-C | 536941 | 2023-01-25T00:58:26Z | 2023-01-25T00:58:26Z | CONTRIBUTOR | > My original idea for compound foreign keys was to turn both of those columns into links, but that doesn't fit here because `database_name` is already part of a different foreign key. it's pretty hard to know what the right thing to do is if a field is part of multiple foreign keys. but, if that's not the case, what about making each of the columns a link. seems like an improvement over the status quo. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
743371103 | |
https://github.com/simonw/datasette/issues/1099#issuecomment-1402898291 | https://api.github.com/repos/simonw/datasette/issues/1099 | 1402898291 | IC_kwDOBm6k_c5Tnodz | 536941 | 2023-01-25T00:55:06Z | 2023-01-25T00:55:06Z | CONTRIBUTOR | I went ahead and spiked something together, in #2003 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
743371103 | |
https://github.com/simonw/datasette/pull/2003#issuecomment-1402898033 | https://api.github.com/repos/simonw/datasette/issues/2003 | 1402898033 | IC_kwDOBm6k_c5TnoZx | 536941 | 2023-01-25T00:54:41Z | 2023-01-25T00:54:41Z | CONTRIBUTOR | @simonw, let me know what you think about this approach! | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1555701851 | |
https://github.com/simonw/datasette/pull/2003#issuecomment-1402894191 | https://api.github.com/repos/simonw/datasette/issues/2003 | 1402894191 | IC_kwDOBm6k_c5Tnndv | 22429695 | 2023-01-25T00:49:23Z | 2023-01-25T00:49:23Z | NONE | # [Codecov](https://codecov.io/gh/simonw/datasette/pull/2003?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report Base: **92.11**% // Head: **92.12**% // Increases project coverage by **`+0.01%`** :tada: > Coverage data is based on head [(`1e5b42f`)](https://codecov.io/gh/simonw/datasette/pull/2003?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) compared to base [(`e4ebef0`)](https://codecov.io/gh/simonw/datasette/commit/e4ebef082de90db4e1b8527abc0d582b7ae0bc9d?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). > Patch coverage: 100.00% of modified lines in pull request are covered. <details><summary>Additional details and impacted files</summary> ```diff @@ Coverage Diff @@ ## main #2003 +/- ## ========================================== + Coverage 92.11% 92.12% +0.01% ========================================== Files 38 38 Lines 5555 5565 +10 ========================================== + Hits 5117 5127 +10 Misses 438 438 ``` | [Impacted Files](https://codecov.io/gh/simonw/datasette/pull/2003?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | | |---|---|---| | [datasette/app.py](https://codecov.io/gh/simonw/datasette/pull/2003?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2FwcC5weQ==) | `94.50% <100.00%> (+0.01%)` | :arrow_up: | | [datasette/filters.py](https://codecov.io/gh/simonw/datasette/pull/2003?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2ZpbHRlcnMucHk=) | `95.73… | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1555701851 | |
https://github.com/simonw/datasette/issues/1099#issuecomment-1402563930 | https://api.github.com/repos/simonw/datasette/issues/1099 | 1402563930 | IC_kwDOBm6k_c5TmW1a | 536941 | 2023-01-24T20:11:11Z | 2023-01-24T20:11:11Z | CONTRIBUTOR | hi @simonw, this bug bit me today. the UX for linking from a table to the foreign key seems tough! the design in the other direction seems a lot easier, for a given primary key detail page, add links back to the tables that refer to the row. would you be open to a PR that solved the second problem but not the first? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
743371103 | |
https://github.com/simonw/datasette/issues/1989#issuecomment-1402347667 | https://api.github.com/repos/simonw/datasette/issues/1989 | 1402347667 | IC_kwDOBm6k_c5TliCT | 116795 | 2023-01-24T17:48:59Z | 2023-01-24T17:48:59Z | NONE | The problem (in my particular use case) with using a VIEW is that I'd need one of the columns to be searchable – but that ([enable-fts](https://github.com/simonw/datasette-search-all)) doesn't work with views :/ __ side-suggestion: I don't know how feasible this might be, but when one column (or table) would be marked as hidden, could the _Download SQLite DB_ link take that into account? 🧐 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1531991339 | |
https://github.com/simonw/datasette/issues/1994#issuecomment-1399957897 | https://api.github.com/repos/simonw/datasette/issues/1994 | 1399957897 | IC_kwDOBm6k_c5TcamJ | 201897 | 2023-01-23T08:21:08Z | 2023-01-23T08:21:08Z | NONE | Me too, on a M1. Not sure if it's compatible? | { "total_count": 1, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 1, "heart": 0, "rocket": 0, "eyes": 0 } |
1536851861 | |
https://github.com/simonw/datasette/issues/2000#issuecomment-1399847946 | https://api.github.com/repos/simonw/datasette/issues/2000 | 1399847946 | IC_kwDOBm6k_c5Tb_wK | 193185 | 2023-01-23T06:08:00Z | 2023-01-23T06:08:00Z | CONTRIBUTOR | Actually, I discovered [your post](https://til.simonwillison.net/datasette/register-new-plugin-hooks) showing how a plugin can add a Datasette hook. That's wild! I've released `datasette-rewrite-sql` that adds this ability, albeit via monkey patching. I had hoped to be able to expose `request` to the hook (or, even better `actor`) when the SQL was being run as a result of a user's HTTP request. But some spelunking in the code makes me suspect that would actually require co-operation from Datasette itself. I'd be happy to be wrong and pointed in the right direction, though! | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1552368054 | |
https://github.com/simonw/datasette/pull/1159#issuecomment-1399606104 | https://api.github.com/repos/simonw/datasette/issues/1159 | 1399606104 | IC_kwDOBm6k_c5TbEtY | 552629 | 2023-01-22T20:58:10Z | 2023-01-22T20:58:10Z | NONE | great initiative, @cldellow :+1: @simonw, if you want to merge this, that would still be welcome :) | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
774332247 | |
https://github.com/simonw/datasette/pull/1159#issuecomment-1399589414 | https://api.github.com/repos/simonw/datasette/issues/1159 | 1399589414 | IC_kwDOBm6k_c5TbAom | 193185 | 2023-01-22T19:48:41Z | 2023-01-22T19:48:41Z | CONTRIBUTOR | Hey @lovasoa, I hope you don't mind - I pulled this PR into [datasette-ui-extras](https://github.com/cldellow/datasette-ui-extras), a plugin I'm making that collects UI tweaks to Datasette. You can apply it to your own Datasette instance by running `datasette install datasette-ui-extras` | { "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
774332247 | |
https://github.com/simonw/datasette/pull/1999#issuecomment-1399341658 | https://api.github.com/repos/simonw/datasette/issues/1999 | 1399341658 | IC_kwDOBm6k_c5TaEJa | 9599 | 2023-01-21T22:06:29Z | 2023-01-21T22:07:30Z | OWNER | Relevant: - #1101 - #1672 - #1062 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1551694938 | |
https://github.com/simonw/datasette/issues/1101#issuecomment-1399341761 | https://api.github.com/repos/simonw/datasette/issues/1101 | 1399341761 | IC_kwDOBm6k_c5TaELB | 9599 | 2023-01-21T22:07:19Z | 2023-01-21T22:07:19Z | OWNER | Idea for supporting streaming with the `register_output_renderer` hook: ```python @hookimpl def register_output_renderer(datasette): return { "extension": "test", "render": render_demo, "can_render": can_render_demo, "render_stream": render_demo_stream, # This is new } ``` So there's a new `"render_stream"` key which can be returned, which if present means that the output renderer supports streaming. I'll play around with the design of that function signature in: - #1999 - #1062 | { "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
749283032 | |
https://github.com/simonw/datasette/pull/1999#issuecomment-1399341151 | https://api.github.com/repos/simonw/datasette/issues/1999 | 1399341151 | IC_kwDOBm6k_c5TaEBf | 9599 | 2023-01-21T22:03:20Z | 2023-01-21T22:03:20Z | OWNER | I think I'm going to have to write a new view function from scratch which completely ignores the existing BaseView/DataView/TableView hierarchy. Here's what I get on the incoming request: ``` (Pdb) request.url, request.full_path, request.host, request.url_vars ('http://127.0.0.1:8001/content/repos.json', '/content/repos.json', '127.0.0.1:8001', {'database': 'content', 'table': 'repos', 'format': 'json'}) ``` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1551694938 | |
https://github.com/simonw/datasette/issues/262#issuecomment-1399184642 | https://api.github.com/repos/simonw/datasette/issues/262 | 1399184642 | IC_kwDOBm6k_c5TZd0C | 9599 | 2023-01-21T05:36:22Z | 2023-01-21T05:41:06Z | OWNER | Maybe `"rows"` should be a default `?_extra=`... but it should be possible to request `"arrays"` instead which would be a list of arrays, more suitable perhaps for custom renderers such as the CSV one. This could be quite neat, in that EVERY key in the JSON representation would be defined as an extra - just some would be on by default. There could even be a mechanism for turning them back off again, maybe using `?_extra=-rows`. In which case maybe `?_extra=` isn't actually the right name for this feature. It could be `?_key=` perhaps, or `?_field=`. Being able to pass `?_field=count,-rows` to get back just the count (and skip executing the count entirely) would be pretty neat. Although `?_only=count` would be tidier. So maybe the pair of `?_only=` and `?_extra=` would make sense. Would `?_only=rows` still return the `"ok"` field so you can always look at that to confirm an error didn't occur? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
323658641 | |
https://github.com/simonw/datasette/issues/262#issuecomment-1399184540 | https://api.github.com/repos/simonw/datasette/issues/262 | 1399184540 | IC_kwDOBm6k_c5TZdyc | 9599 | 2023-01-21T05:35:32Z | 2023-01-21T05:35:32Z | OWNER | It's annoying that the https://docs.datasette.io/en/0.64.1/plugin_hooks.html#register-output-renderer-datasette plugin hook passes `rows` as "list of sqlite3.Row objects" - I'd prefer it if that plugin hook worked with JSON data, not `sqlite3.Row`. https://docs.datasette.io/en/0.64.1/plugin_hooks.html#render-cell-row-value-column-table-database-datasette is documented as accepting `Row` but actually gets `CustomRow`, see: - #1973 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
323658641 | |
https://github.com/simonw/datasette/issues/262#issuecomment-1399178823 | https://api.github.com/repos/simonw/datasette/issues/262 | 1399178823 | IC_kwDOBm6k_c5TZcZH | 9599 | 2023-01-21T04:54:49Z | 2023-01-21T04:54:49Z | OWNER | I pushed my prototype so far, going to start a draft PR for it. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
323658641 | |
https://github.com/simonw/datasette/issues/262#issuecomment-1399178591 | https://api.github.com/repos/simonw/datasette/issues/262 | 1399178591 | IC_kwDOBm6k_c5TZcVf | 9599 | 2023-01-21T04:53:15Z | 2023-01-21T04:53:15Z | OWNER | Implementing this to work with the `.json` extension is going to be a lot harder. The challenge here is that we're working with the whole `BaseView()` v.s. `TableView()` abstraction, which I've been wanting to get rid of for a long time. `BaseView()` calls `.data()` and expects to get back a `(data, extra_template_data, templates)` tuple - then if a format is in play (`.json` or `.geojson` or similar from a plugin) it hands off `data` to that. If `.csv` is involved it does something special, in order to support streaming responses. And if it's regular HTML it calls `await extra_template_data()` and combines that with `data` and passes it to the template. I want this to work completely differently: I want the formats (including HTML) to have the option of adding some extra `?_extra=` extras, then I want HTML to be able to render the page entirely from the JSON if necessary. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
323658641 | |
https://github.com/simonw/datasette/issues/262#issuecomment-1399145981 | https://api.github.com/repos/simonw/datasette/issues/262 | 1399145981 | IC_kwDOBm6k_c5TZUX9 | 9599 | 2023-01-21T01:56:52Z | 2023-01-21T01:56:52Z | OWNER | Got first prototype working using `asyncinject` and it's pretty nice: ```diff diff --git a/datasette/views/table.py b/datasette/views/table.py index ad45ecd3..c8690b22 100644 --- a/datasette/views/table.py +++ b/datasette/views/table.py @@ -2,6 +2,7 @@ import asyncio import itertools import json +from asyncinject import Registry import markupsafe from datasette.plugins import pm @@ -538,57 +539,60 @@ class TableView(DataView): # Execute the main query! results = await db.execute(sql, params, truncate=True, **extra_args) - # Calculate the total count for this query - count = None - if ( - not db.is_mutable - and self.ds.inspect_data - and count_sql == f"select count(*) from {table_name} " - ): - # We can use a previously cached table row count - try: - count = self.ds.inspect_data[database_name]["tables"][table_name][ - "count" - ] - except KeyError: - pass - - # Otherwise run a select count(*) ... - if count_sql and count is None and not nocount: - try: - count_rows = list(await db.execute(count_sql, from_sql_params)) - count = count_rows[0][0] - except QueryInterrupted: - pass - - # Faceting - if not self.ds.setting("allow_facet") and any( - arg.startswith("_facet") for arg in request.args - ): - raise BadRequest("_facet= is not allowed") + # Resolve extras + extras = _get_extras(request) + if request.args.getlist("_facet"): + extras.add("facet_results") - # pylint: disable=no-member - facet_classes = list( - itertools.chain.from_iterable(pm.hook.register_facet_classes()) - ) - facet_results = {} - facets_timed_out = [] - facet_instances = [] - for klass in f… | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
323658641 | |
https://github.com/simonw/datasette/issues/1998#issuecomment-1398768399 | https://api.github.com/repos/simonw/datasette/issues/1998 | 1398768399 | IC_kwDOBm6k_c5TX4MP | 9599 | 2023-01-20T18:19:06Z | 2023-01-20T18:19:06Z | OWNER | Simplest solution would be to ditch the `version_option` decorator and roll a custom option based on it instead, imitating what this code does: https://github.com/pallets/click/blob/7586834cab38c5592d9d6de3ee0ebe75d4353bfb/src/click/decorators.py#L413-L524 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1551113681 | |
https://github.com/simonw/datasette/issues/1998#issuecomment-1398767813 | https://api.github.com/repos/simonw/datasette/issues/1998 | 1398767813 | IC_kwDOBm6k_c5TX4DF | 9599 | 2023-01-20T18:18:27Z | 2023-01-20T18:18:27Z | OWNER | Fell down a bit of a rabbit hole trying to figure out how to get Click's `version_option()` to evaluate a custom message. Got this far: ```python class _VersionMessage(UserString): @property def data(self): return "%(prog)s, version %(version)s (SQLite {})".format( sqlite3.connect(":memory:").execute("select sqlite_version()").fetchone()[0] ) @data.setter def data(self, value): pass @click.group(cls=DefaultGroup, default="serve", default_if_no_args=True) @click.version_option(version=__version__, message=_VersionMessage("")) def cli(): """ Datasette is an open source multi-tool for exploring and publishing data \b About Datasette: https://datasette.io/ Full documentation: https://docs.datasette.io/ """ ``` But now: ``` % datasette --version %(prog)s, version %(version)s (SQLite 3.40.1) ``` I was trying to avoid running that `select sqlite_version()` thing unless the `--version` option was used. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1551113681 | |
https://github.com/simonw/datasette/issues/262#issuecomment-1397942113 | https://api.github.com/repos/simonw/datasette/issues/262 | 1397942113 | IC_kwDOBm6k_c5TUudh | 9599 | 2023-01-20T05:33:00Z | 2023-01-20T05:33:00Z | OWNER | I'm going to write code which parses `?_extra=` in the comma separated or multiple parameter format and then looks up functions in a dictionary. It will return an error if you ask for an extra that does not exist. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
323658641 |