issue_comments
9,947 rows sorted by issue descending
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 |
---|---|---|---|---|---|---|---|---|---|---|---|
1556228395 | https://github.com/simonw/sqlite-utils/issues/547#issuecomment-1556228395 | https://api.github.com/repos/simonw/sqlite-utils/issues/547 | IC_kwDOCGYnMM5cwikr | simonw 9599 | 2023-05-21T17:11:15Z | 2023-05-21T17:11:15Z | OWNER | This will be a cosmetic change to the CLI output only - the options to save data to the database and the Python API function will continue to return `[(None, 158)]`. I can add an optimization though to avoid running the SQL count query if we know that it's all `null`. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | No need to show common values if everything is null 1718572201 | |
1556213031 | https://github.com/simonw/sqlite-utils/pull/546#issuecomment-1556213031 | https://api.github.com/repos/simonw/sqlite-utils/issues/546 | IC_kwDOCGYnMM5cwe0n | codecov[bot] 22429695 | 2023-05-21T15:56:05Z | 2023-05-21T16:18:03Z | NONE | ## [Codecov](https://app.codecov.io/gh/simonw/sqlite-utils/pull/546?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report Patch coverage: **`93.75`**% and no project coverage change. > Comparison is base [(`b3b100d`)](https://app.codecov.io/gh/simonw/sqlite-utils/commit/b3b100d7f5b2a76ccd4bfe8b0301a29e321d0375?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 96.30% compared to head [(`9f23e68`)](https://app.codecov.io/gh/simonw/sqlite-utils/pull/546?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 96.31%. > :exclamation: Current head 9f23e68 differs from pull request most recent head 2eca17d. Consider uploading reports for the commit 2eca17d to get more accurate results <details><summary>Additional details and impacted files</summary> ```diff @@ Coverage Diff @@ ## main #546 +/- ## ======================================= Coverage 96.30% 96.31% ======================================= Files 6 6 Lines 2707 2712 +5 ======================================= + Hits 2607 2612 +5 Misses 100 100 ``` | [Impacted Files](https://app.codecov.io/gh/simonw/sqlite-utils/pull/546?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | | |---|---|---| | [sqlite\_utils/db.py](https://app.codecov.io/gh/simonw/sqlite-utils/pull/546?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-c3FsaXRlX3V0aWxzL2RiLnB5) | `97.37% <90.90%> (+<0.01%)` | :arrow_up: | | [sqlite\_utils/cli.py](https://app.codecov.io/gh/simonw/sqlite-utils/pull/546?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign… | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Analyze tables options: --common-limit, --no-most, --no-least 1718550688 | |
1556213396 | https://github.com/simonw/sqlite-utils/pull/546#issuecomment-1556213396 | https://api.github.com/repos/simonw/sqlite-utils/issues/546 | IC_kwDOCGYnMM5cwe6U | simonw 9599 | 2023-05-21T15:58:12Z | 2023-05-21T16:18:46Z | OWNER | Documentation preview: - https://sqlite-utils--546.org.readthedocs.build/en/546/cli.html#cli-analyze-tables - https://sqlite-utils--546.org.readthedocs.build/en/546/cli-reference.html#analyze-tables - https://sqlite-utils--546.org.readthedocs.build/en/546/python-api.html#analyzing-a-column - https://sqlite-utils--546.org.readthedocs.build/en/546/reference.html#sqlite_utils.db.Table.analyze_column | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Analyze tables options: --common-limit, --no-most, --no-least 1718550688 | |
1556189823 | https://github.com/simonw/sqlite-utils/issues/545#issuecomment-1556189823 | https://api.github.com/repos/simonw/sqlite-utils/issues/545 | IC_kwDOCGYnMM5cwZJ_ | simonw 9599 | 2023-05-21T14:09:59Z | 2023-05-21T14:09:59Z | OWNER | I don't want to add `trogon` as a default dependency because it's a little heavy - it pulls in all of Rich and Textual as well. People who use `sqlite-utils` just for its Python API won't benefit from this - it's a CLI feature only. But I have a `sqlite-utils install ...` command for helping people to install packages into the same virtual environment as `sqlite-utils` no matter how they installed that tool: https://sqlite-utils.datasette.io/en/stable/cli.html#cli-install So I can treat Trogon as an optional dependency and add the `sqlite-utils tui` command only if that package is also installed. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Try out Trogon for a tui interface 1718517882 | |
1556190531 | https://github.com/simonw/sqlite-utils/issues/545#issuecomment-1556190531 | https://api.github.com/repos/simonw/sqlite-utils/issues/545 | IC_kwDOCGYnMM5cwZVD | simonw 9599 | 2023-05-21T14:13:43Z | 2023-05-21T14:13:43Z | OWNER | OK, this works! ![trogon](https://github.com/simonw/sqlite-utils/assets/9599/2ae194c5-ec82-471a-9d1b-b01b3f2632f3) To try it out, install that branch from GitHub: pip install https://github.com/simonw/sqlite-utils/archive/refs/heads/trogon.zip Then run this: sqlite-utils install trogon And this: sqlite-utils tui | {"total_count": 5, "+1": 2, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 3, "eyes": 0} | Try out Trogon for a tui interface 1718517882 | |
1556191894 | https://github.com/simonw/sqlite-utils/issues/545#issuecomment-1556191894 | https://api.github.com/repos/simonw/sqlite-utils/issues/545 | IC_kwDOCGYnMM5cwZqW | simonw 9599 | 2023-05-21T14:20:14Z | 2023-05-21T14:20:14Z | OWNER | Opened a feature request for customizing the help and command name: - https://github.com/Textualize/trogon/issues/2 | {"total_count": 2, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 1, "rocket": 0, "eyes": 0} | Try out Trogon for a tui interface 1718517882 | |
1556210844 | https://github.com/simonw/sqlite-utils/issues/545#issuecomment-1556210844 | https://api.github.com/repos/simonw/sqlite-utils/issues/545 | IC_kwDOCGYnMM5cweSc | simonw 9599 | 2023-05-21T15:44:10Z | 2023-05-21T15:44:10Z | OWNER | It looks like `nargs=-1` on a positional argument isn't yet supported - opened an issue here: - https://github.com/Textualize/trogon/issues/4 | {"total_count": 1, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 1, "rocket": 0, "eyes": 0} | Try out Trogon for a tui interface 1718517882 | |
1556247818 | https://github.com/simonw/sqlite-utils/issues/545#issuecomment-1556247818 | https://api.github.com/repos/simonw/sqlite-utils/issues/545 | IC_kwDOCGYnMM5cwnUK | simonw 9599 | 2023-05-21T18:17:46Z | 2023-05-21T18:17:46Z | OWNER | Draft documentation: https://sqlite-utils--549.org.readthedocs.build/en/549/cli.html#cli-tui | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Try out Trogon for a tui interface 1718517882 | |
1556269616 | https://github.com/simonw/sqlite-utils/issues/545#issuecomment-1556269616 | https://api.github.com/repos/simonw/sqlite-utils/issues/545 | IC_kwDOCGYnMM5cwsow | simonw 9599 | 2023-05-21T19:33:13Z | 2023-05-21T19:33:13Z | OWNER | Now released: https://sqlite-utils.datasette.io/en/stable/changelog.html#v3-32 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Try out Trogon for a tui interface 1718517882 | |
1556211643 | https://github.com/simonw/sqlite-utils/issues/544#issuecomment-1556211643 | https://api.github.com/repos/simonw/sqlite-utils/issues/544 | IC_kwDOCGYnMM5cwee7 | simonw 9599 | 2023-05-21T15:48:17Z | 2023-05-21T15:48:17Z | OWNER | I generated the commit message in https://github.com/simonw/sqlite-utils/commit/1c1991b447a1ddd3d61d9d4a8a1d6a9da47ced20 using `git diff | llm --system 'describe this change'`. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | New options for analyze-tables --common-limit --no-most and --no-least 1718515590 | |
1556225788 | https://github.com/simonw/sqlite-utils/issues/544#issuecomment-1556225788 | https://api.github.com/repos/simonw/sqlite-utils/issues/544 | IC_kwDOCGYnMM5cwh78 | simonw 9599 | 2023-05-21T17:02:05Z | 2023-05-21T17:02:05Z | OWNER | New docs: - https://sqlite-utils.datasette.io/en/latest/cli.html#cli-analyze-tables - https://sqlite-utils.datasette.io/en/latest/cli-reference.html#analyze-tables - https://sqlite-utils.datasette.io/en/latest/python-api.html#analyzing-a-column - https://sqlite-utils.datasette.io/en/latest/reference.html#sqlite_utils.db.Table.analyze_column New help output: ``` % sqlite-utils analyze-tables --help Usage: sqlite-utils analyze-tables [OPTIONS] PATH [TABLES]... Analyze the columns in one or more tables Example: sqlite-utils analyze-tables data.db trees Options: -c, --column TEXT Specific columns to analyze --save Save results to _analyze_tables table --common-limit INTEGER How many common values --no-most Skip most common values --no-least Skip least common values --load-extension TEXT Path to SQLite extension, with optional :entrypoint -h, --help Show this message and exit. ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | New options for analyze-tables --common-limit --no-most and --no-least 1718515590 | |
1547944971 | https://github.com/simonw/datasette/pull/2075#issuecomment-1547944971 | https://api.github.com/repos/simonw/datasette/issues/2075 | IC_kwDOBm6k_c5cQ8QL | codecov[bot] 22429695 | 2023-05-15T14:12:20Z | 2023-05-15T14:12:20Z | NONE | ## [Codecov](https://app.codecov.io/gh/simonw/datasette/pull/2075?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 [(`49184c5`)](https://app.codecov.io/gh/simonw/datasette/commit/49184c569cd70efbda4f3f062afef3a34401d8d5?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.40% compared to head [(`b99e1d3`)](https://app.codecov.io/gh/simonw/datasette/pull/2075?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.40%. <details><summary>Additional details and impacted files</summary> ```diff @@ Coverage Diff @@ ## main #2075 +/- ## ======================================= Coverage 92.40% 92.40% ======================================= Files 38 38 Lines 5751 5751 ======================================= Hits 5314 5314 Misses 437 437 ``` </details> [:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/simonw/datasette/pull/2075?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+Willison). | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Bump sphinx from 6.1.3 to 7.0.1 1710164693 | |
1546117538 | https://github.com/simonw/datasette/issues/2073#issuecomment-1546117538 | https://api.github.com/repos/simonw/datasette/issues/2073 | IC_kwDOBm6k_c5cJ-Gi | simonw 9599 | 2023-05-12T18:21:38Z | 2023-05-12T18:21:38Z | OWNER | https://latest.datasette.io/fixtures doesn't currently have a view with any integer columns in it, making this bug harder to demonstrate there. I can't replicate the bug using https://datasette.io/content/plugins?_facet=stargazers_count&stargazers_count=3 - I would expect that not to work correctly. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Faceting doesn't work against integer columns in views 1708030220 | |
1546119773 | https://github.com/simonw/datasette/issues/2073#issuecomment-1546119773 | https://api.github.com/repos/simonw/datasette/issues/2073 | IC_kwDOBm6k_c5cJ-pd | simonw 9599 | 2023-05-12T18:24:07Z | 2023-05-12T18:24:07Z | OWNER | Here's a demo of this breaking in Datasette Lite: https://lite.datasette.io/?sql=https://gist.github.com/simonw/261564c0ca01567df6eeb9b222b8be84&json=https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2Fweb-features%2Findex.json#/data/baseline?_filter_column_1=is_baseline&_filter_op_1=exact&_filter_value_1=1&_filter_column_2=&_filter_op_2=notnull__1&_filter_value_2=1&_filter_column=&_filter_op=exact&_filter_value=&_sort=&_facet=is_baseline <img width="609" alt="image" src="https://github.com/simonw/datasette/assets/9599/3c23ae6e-7fb0-41d4-92b8-421c400a731a"> Here's a SQL query that demonstrates the underlying issue: ```sql select 'working', count(*) from baseline where is_baseline = 1 union all select 'broken', count(*) from baseline where is_baseline = '1' ``` https://lite.datasette.io/?sql=https://gist.github.com/simonw/261564c0ca01567df6eeb9b222b8be84&json=https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2Fweb-features%2Findex.json#/data?sql=select+%27working%27%2C+count%28*%29+from+baseline+where+is_baseline+%3D+1%0Aunion+all%0Aselect+%27broken%27%2C+count%28*%29+from+baseline+where+is_baseline+%3D+%271%27 <img width="673" alt="image" src="https://github.com/simonw/datasette/assets/9599/867914f8-8cef-432c-a518-2739d1caf964"> | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Faceting doesn't work against integer columns in views 1708030220 | |
1540491751 | https://github.com/simonw/datasette/issues/2070#issuecomment-1540491751 | https://api.github.com/repos/simonw/datasette/issues/2070 | IC_kwDOBm6k_c5b0gnn | simonw 9599 | 2023-05-09T16:23:12Z | 2023-05-09T16:23:12Z | OWNER | Added a actions `BRANCH_PREVIEW_VERCEL_TOKEN` secret to this repository. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Mechanism for deploying a preview of a branch using Vercel 1702354223 | |
1540494121 | https://github.com/simonw/datasette/issues/2070#issuecomment-1540494121 | https://api.github.com/repos/simonw/datasette/issues/2070 | IC_kwDOBm6k_c5b0hMp | simonw 9599 | 2023-05-09T16:25:00Z | 2023-05-09T16:25:00Z | OWNER | Can now be used here: https://github.com/simonw/datasette/actions/workflows/deploy-branch-preview.yml | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Mechanism for deploying a preview of a branch using Vercel 1702354223 | |
1539052467 | https://github.com/simonw/sqlite-utils/issues/542#issuecomment-1539052467 | https://api.github.com/repos/simonw/sqlite-utils/issues/542 | IC_kwDOCGYnMM5bvBOz | simonw 9599 | 2023-05-08T21:07:41Z | 2023-05-08T21:07:41Z | OWNER | Relevant commits (will mostly revert these): - https://github.com/simonw/sqlite-utils/commit/455c35b512895c19bf922c2b804d750d27cb8dbd - https://github.com/simonw/sqlite-utils/commit/e0ec4c345129996011951e400388fd74865f65a2 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Remove `skip_false=True` and `--no-skip-false` in `sqlite-utils` 4.0 1700936245 | |
1538963959 | https://github.com/simonw/sqlite-utils/issues/541#issuecomment-1538963959 | https://api.github.com/repos/simonw/sqlite-utils/issues/541 | IC_kwDOCGYnMM5burn3 | simonw 9599 | 2023-05-08T19:59:34Z | 2023-05-08T19:59:34Z | OWNER | There are 8 failing tests left: ``` ==== short test summary info ==== FAILED tests/test_cli_memory.py::test_memory_csv[False-test] - pytest.PytestUnraisableExceptionWarning: Exception ignored in: <_io.FileIO [closed]> FAILED tests/test_cli_memory.py::test_memory_csv[False-t] - pytest.PytestUnraisableExceptionWarning: Exception ignored in: <_io.FileIO [closed]> FAILED tests/test_cli_memory.py::test_memory_csv[False-t1] - pytest.PytestUnraisableExceptionWarning: Exception ignored in: <_io.FileIO [closed]> FAILED tests/test_cli_memory.py::test_memory_tsv[False] - pytest.PytestUnraisableExceptionWarning: Exception ignored in: <_io.FileIO [closed]> FAILED tests/test_cli_memory.py::test_memory_dump[extra_args0] - pytest.PytestUnraisableExceptionWarning: Exception ignored in: <_io.FileIO [closed]> FAILED tests/test_cli_memory.py::test_memory_two_files_with_same_stem - pytest.PytestUnraisableExceptionWarning: Exception ignored in: <_io.FileIO [closed]> FAILED tests/test_recipes.py::test_dateparse_errors[None-parsedate] - pytest.PytestUnraisableExceptionWarning: Exception ignored in: <function Table.convert.<locals>.convert_value at 0x106bcaca0> FAILED tests/test_recipes.py::test_dateparse_errors[None-parsedatetime] - pytest.PytestUnraisableExceptionWarning: Exception ignored in: <function Table.convert.<locals>.convert_value at 0x106bc9620> ERROR tests/test_cli.py::test_upsert_analyze - pytest.PytestUnraisableExceptionWarning: Exception ignored in: <_io.FileIO [closed]> ==== 8 failed, 894 passed, 4 skipped, 1 error in 6.27s ==== ``` Full traceback here: https://gist.github.com/simonw/b40b3e814729d6c02a0302a84ce54d9e | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Get tests to pass with `pytest -Werror` 1700840265 | |
1537513653 | https://github.com/simonw/sqlite-utils/issues/540#issuecomment-1537513653 | https://api.github.com/repos/simonw/sqlite-utils/issues/540 | IC_kwDOCGYnMM5bpJi1 | simonw 9599 | 2023-05-07T18:37:59Z | 2023-05-07T18:38:19Z | OWNER | Useful comment here: - https://github.com/urllib3/urllib3/issues/2168#issuecomment-1537360928 > I faced the same issue. I switched to a different Python kernel (3.11.2) and it worked. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | sphinx.builders.linkcheck build error 1699184583 | |
1537513912 | https://github.com/simonw/sqlite-utils/issues/540#issuecomment-1537513912 | https://api.github.com/repos/simonw/sqlite-utils/issues/540 | IC_kwDOCGYnMM5bpJm4 | simonw 9599 | 2023-05-07T18:39:29Z | 2023-05-07T18:39:29Z | OWNER | https://readthedocs.org/projects/sqlite-utils/builds/20513034/ said: > Problem in your project's configuration. Invalid "python.version": expected one of (2, 2.7, 3, 3.5, 3.6, 3.7, 3.8, pypy3.5), got 3.11 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | sphinx.builders.linkcheck build error 1699184583 | |
1537514069 | https://github.com/simonw/sqlite-utils/issues/540#issuecomment-1537514069 | https://api.github.com/repos/simonw/sqlite-utils/issues/540 | IC_kwDOCGYnMM5bpJpV | simonw 9599 | 2023-05-07T18:40:18Z | 2023-05-07T18:40:18Z | OWNER | https://docs.readthedocs.io/en/stable/config-file/v2.html suggests: ```yaml build: os: ubuntu-22.04 tools: python: "3.11" ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | sphinx.builders.linkcheck build error 1699184583 | |
1537744000 | https://github.com/simonw/sqlite-utils/issues/540#issuecomment-1537744000 | https://api.github.com/repos/simonw/sqlite-utils/issues/540 | IC_kwDOCGYnMM5bqByA | pquentin 42327 | 2023-05-08T04:56:12Z | 2023-05-08T04:56:12Z | NONE | Hey @simonw, urllib3 maintainer here :wave: Sorry for breaking your CI. I understand you may prefer to pin the Python version, but note that specifying just `python: "3"` will get you the latest. We use that in urllib3: https://github.com/urllib3/urllib3/blob/main/.readthedocs.yml I can open PRs to sqlite-utils / datasette if you're interested | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | sphinx.builders.linkcheck build error 1699184583 | |
1537507394 | https://github.com/simonw/sqlite-utils/issues/539#issuecomment-1537507394 | https://api.github.com/repos/simonw/sqlite-utils/issues/539 | IC_kwDOCGYnMM5bpIBC | simonw 9599 | 2023-05-07T18:08:44Z | 2023-05-07T18:08:44Z | OWNER | Prototype: ```diff diff --git a/docs/cli-reference.rst b/docs/cli-reference.rst index 153e5f9..c830518 100644 --- a/docs/cli-reference.rst +++ b/docs/cli-reference.rst @@ -124,6 +124,7 @@ See :ref:`cli_query`. --json-cols Detect JSON cols and output them as JSON, not escaped strings -r, --raw Raw output, first column of first row + --raw-lines Raw output, first column of each row -p, --param <TEXT TEXT>... Named :parameters for SQL query --functions TEXT Python code defining one or more custom SQL functions @@ -192,6 +193,7 @@ See :ref:`cli_memory`. --json-cols Detect JSON cols and output them as JSON, not escaped strings -r, --raw Raw output, first column of first row + --raw-lines Raw output, first column of each row -p, --param <TEXT TEXT>... Named :parameters for SQL query --encoding TEXT Character encoding for CSV input, defaults to utf-8 diff --git a/sqlite_utils/cli.py b/sqlite_utils/cli.py index d25b1df..da0e4b6 100644 --- a/sqlite_utils/cli.py +++ b/sqlite_utils/cli.py @@ -1653,6 +1653,7 @@ def drop_view(path, view, ignore, load_extension): ) @output_options @click.option("-r", "--raw", is_flag=True, help="Raw output, first column of first row") +@click.option("--raw-lines", is_flag=True, help="Raw output, first column of each row") @click.option( "-p", "--param", @@ -1677,6 +1678,7 @@ def query( fmt, json_cols, raw, + raw_lines, param, load_extension, functions, @@ -1700,7 +1702,19 @@ def query( _register_functions(db, functions) _execute_query( - db, sql, param, raw, table, csv, tsv, no_headers, fmt, nl, arrays, json_cols + db, + sql, + par… | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | `--raw-lines` option, like `--raw` for multiple lines 1699174055 | |
1537507525 | https://github.com/simonw/sqlite-utils/issues/539#issuecomment-1537507525 | https://api.github.com/repos/simonw/sqlite-utils/issues/539 | IC_kwDOCGYnMM5bpIDF | simonw 9599 | 2023-05-07T18:09:09Z | 2023-05-07T18:09:09Z | OWNER | I'm tempted to upgrade `--raw` to do this instead, but that would be a breaking change. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | `--raw-lines` option, like `--raw` for multiple lines 1699174055 | |
1537507676 | https://github.com/simonw/sqlite-utils/issues/539#issuecomment-1537507676 | https://api.github.com/repos/simonw/sqlite-utils/issues/539 | IC_kwDOCGYnMM5bpIFc | simonw 9599 | 2023-05-07T18:09:43Z | 2023-05-07T18:09:54Z | OWNER | This worked: ```bash sqlite-utils memory /tmp/books3.json:nl \ 'select name from books3' --raw-lines > titles.txt ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | `--raw-lines` option, like `--raw` for multiple lines 1699174055 | |
1537514610 | https://github.com/simonw/sqlite-utils/issues/539#issuecomment-1537514610 | https://api.github.com/repos/simonw/sqlite-utils/issues/539 | IC_kwDOCGYnMM5bpJxy | simonw 9599 | 2023-05-07T18:43:24Z | 2023-05-07T18:43:24Z | OWNER | Documentation: - https://sqlite-utils.datasette.io/en/latest/cli.html#returning-raw-data-such-as-binary-content - https://sqlite-utils.datasette.io/en/latest/cli-reference.html#query - https://sqlite-utils.datasette.io/en/latest/cli-reference.html#memory | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | `--raw-lines` option, like `--raw` for multiple lines 1699174055 | |
1537277919 | https://github.com/simonw/datasette/issues/2069#issuecomment-1537277919 | https://api.github.com/repos/simonw/datasette/issues/2069 | IC_kwDOBm6k_c5boP_f | yqlbu 31861128 | 2023-05-07T03:17:35Z | 2023-05-07T03:17:35Z | NONE | Some updates: I notice that there is an option in the CLI where we can explicitly set `immutable` mode when spinning up the server ```console Options: -i, --immutable PATH Database files to open in immutable mode ``` Then, the question is - how can I disable immutable mode in the deployed instance on Vercel? | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | [BUG] Cannot insert new data to deployed instance 1698865182 | |
1538793817 | https://github.com/simonw/sqlite-utils/issues/538#issuecomment-1538793817 | https://api.github.com/repos/simonw/sqlite-utils/issues/538 | IC_kwDOCGYnMM5buCFZ | simonw 9599 | 2023-05-08T17:55:10Z | 2023-05-08T17:55:10Z | OWNER | Confirmed - I added this test and it fails: ```python def test_upsert_all_not_null(fresh_db): # https://github.com/simonw/sqlite-utils/issues/538 fresh_db["comments"].upsert_all( [{"id": 1, "name": "Cleo"}], pk="id", not_null=["name"], ) assert list(fresh_db["comments"].rows) == [{"id": 1, "name": "Cleo"}] ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | `table.upsert_all` fails to write rows when `not_null` is present 1695428235 | |
1538801855 | https://github.com/simonw/sqlite-utils/issues/538#issuecomment-1538801855 | https://api.github.com/repos/simonw/sqlite-utils/issues/538 | IC_kwDOCGYnMM5buEC_ | simonw 9599 | 2023-05-08T18:00:17Z | 2023-05-08T18:00:17Z | OWNER | From time in the debugger, after creating the table it ends up doing this: ``` (Pdb) queries_and_params [ ('INSERT OR IGNORE INTO [comments]([id]) VALUES(?);', [1]), ('UPDATE [comments] SET [name] = ? WHERE [id] = ?', ['Cleo', 1]) ] ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | `table.upsert_all` fails to write rows when `not_null` is present 1695428235 | |
1538887361 | https://github.com/simonw/sqlite-utils/issues/538#issuecomment-1538887361 | https://api.github.com/repos/simonw/sqlite-utils/issues/538 | IC_kwDOCGYnMM5buY7B | simonw 9599 | 2023-05-08T19:01:20Z | 2023-05-08T19:01:20Z | OWNER | Here's the problem: ```python import sqlite3 db = sqlite3.connect(":memory:") db.execute('create table foo (id integer primary key, name not null)') db.execute('insert into foo (id) values (1)') ``` Produces: ``` IntegrityError: NOT NULL constraint failed: foo.name ``` But this: ```python db.execute('insert or ignore into foo (id) values (1)') ``` Completes without an exception. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | `table.upsert_all` fails to write rows when `not_null` is present 1695428235 | |
1538889482 | https://github.com/simonw/sqlite-utils/issues/538#issuecomment-1538889482 | https://api.github.com/repos/simonw/sqlite-utils/issues/538 | IC_kwDOCGYnMM5buZcK | simonw 9599 | 2023-05-08T19:02:38Z | 2023-05-08T19:02:38Z | OWNER | Here's the code at fault: https://github.com/simonw/sqlite-utils/blob/80763edaa2bdaf1113717378b8d62075c4dcbcfb/sqlite_utils/db.py#L2774-L2788 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | `table.upsert_all` fails to write rows when `not_null` is present 1695428235 | |
1538893329 | https://github.com/simonw/sqlite-utils/issues/538#issuecomment-1538893329 | https://api.github.com/repos/simonw/sqlite-utils/issues/538 | IC_kwDOCGYnMM5buaYR | simonw 9599 | 2023-05-08T19:04:47Z | 2023-05-08T19:04:47Z | OWNER | This feels like a fundamental flaw in the way upserts are implemented by `sqlite-utils`. One fix would be to switch to using the `UPSERT` feature in SQLite: https://www.sqlite.org/lang_UPSERT.html But... > UPSERT syntax was added to SQLite with version 3.24.0 (2018-06-04). I still want to support SQLite versions earlier than that. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | `table.upsert_all` fails to write rows when `not_null` is present 1695428235 | |
1538903556 | https://github.com/simonw/sqlite-utils/issues/538#issuecomment-1538903556 | https://api.github.com/repos/simonw/sqlite-utils/issues/538 | IC_kwDOCGYnMM5buc4E | simonw 9599 | 2023-05-08T19:11:24Z | 2023-05-08T19:13:23Z | OWNER | I could detect if this happens using `cursor.rowcount` - not sure how I would recover from it though. This would also require some major re-engineering, since currently it all works by generating a list of SQL queries in advance and applying them inside a loop in `.insert_chunk()`: https://github.com/simonw/sqlite-utils/blob/80763edaa2bdaf1113717378b8d62075c4dcbcfb/sqlite_utils/db.py#L2839-L2878 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | `table.upsert_all` fails to write rows when `not_null` is present 1695428235 | |
1538910894 | https://github.com/simonw/sqlite-utils/issues/538#issuecomment-1538910894 | https://api.github.com/repos/simonw/sqlite-utils/issues/538 | IC_kwDOCGYnMM5buequ | simonw 9599 | 2023-05-08T19:16:52Z | 2023-05-08T19:17:00Z | OWNER | How about if I had logic which checked that all not-null columns were provided in the call to `upsert_all()` - and if they were, modified the `INSERT OR IGNORE INTO` to include a placeholder value for those columns that would then be fixed by the later `UPDATE`? Something like this: ```python [ ('INSERT OR IGNORE INTO [comments]([id], name) VALUES(?, ?);', [1, '']), ('UPDATE [comments] SET [name] = ? WHERE [id] = ?', ['Cleo', 1]) ] ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | `table.upsert_all` fails to write rows when `not_null` is present 1695428235 | |
1538921774 | https://github.com/simonw/sqlite-utils/issues/538#issuecomment-1538921774 | https://api.github.com/repos/simonw/sqlite-utils/issues/538 | IC_kwDOCGYnMM5buhUu | simonw 9599 | 2023-05-08T19:24:41Z | 2023-05-08T19:24:41Z | OWNER | That fix seems to work! | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | `table.upsert_all` fails to write rows when `not_null` is present 1695428235 | |
1538975545 | https://github.com/simonw/sqlite-utils/issues/538#issuecomment-1538975545 | https://api.github.com/repos/simonw/sqlite-utils/issues/538 | IC_kwDOCGYnMM5buuc5 | xavdid 1231935 | 2023-05-08T20:06:35Z | 2023-05-08T20:06:35Z | NONE | perfect, thank you! | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | `table.upsert_all` fails to write rows when `not_null` is present 1695428235 | |
1547911570 | https://github.com/simonw/datasette/pull/2068#issuecomment-1547911570 | https://api.github.com/repos/simonw/datasette/issues/2068 | IC_kwDOBm6k_c5cQ0GS | dependabot[bot] 49699333 | 2023-05-15T13:59:35Z | 2023-05-15T13:59:35Z | CONTRIBUTOR | Superseded by #2075. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Bump sphinx from 6.1.3 to 7.0.0 1690842199 | |
1532304714 | https://github.com/simonw/datasette/issues/2067#issuecomment-1532304714 | https://api.github.com/repos/simonw/datasette/issues/2067 | IC_kwDOBm6k_c5bVR1K | justmars 39538958 | 2023-05-03T00:16:03Z | 2023-05-03T00:16:03Z | NONE | Curiously, after running commands on the database that was litestream-restored, datasette starts to work again, e.g. ```sh litestream restore -o data/db.sqlite s3://mytestbucketxx/db datasette data/db.sqlite # fails (OperationalError described above) ``` ```sh litestream restore -o data/db.sqlite s3://mytestbucketxx/db sqlite-utils enable-wal data/db.sqlite datasette data/db.sqlite # works ``` ```sh litestream restore -o data/db.sqlite s3://mytestbucketxx/db sqlite-utils optimize data/db.sqlite datasette data/db.sqlite # works ``` ```sh litestream restore -o data/db.sqlite s3://mytestbucketxx/db sqlite3 data/db.sqlite ".clone test.db" datasette test.db # works ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Litestream-restored db: errors on 3.11 and 3.10.8; but works on py3.10.7 and 3.10.6 1690765434 | |
1524637376 | https://github.com/simonw/datasette/issues/2066#issuecomment-1524637376 | https://api.github.com/repos/simonw/datasette/issues/2066 | IC_kwDOBm6k_c5a4B7A | simonw 9599 | 2023-04-27T03:50:19Z | 2023-04-27T03:50:19Z | OWNER | Having trouble replicating this on my laptop. I tried a fresh virtual environment with fresh packages (in case this is a `httpx` change) but this passed: pytest tests/test_csv.py | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Failing test: httpx.InvalidURL: URL too long 1686042269 | |
1524638233 | https://github.com/simonw/datasette/issues/2066#issuecomment-1524638233 | https://api.github.com/repos/simonw/datasette/issues/2066 | IC_kwDOBm6k_c5a4CIZ | simonw 9599 | 2023-04-27T03:50:51Z | 2023-04-27T03:50:51Z | OWNER | Failure was on 3.7. I'll try that. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Failing test: httpx.InvalidURL: URL too long 1686042269 | |
1524648995 | https://github.com/simonw/datasette/issues/2066#issuecomment-1524648995 | https://api.github.com/repos/simonw/datasette/issues/2066 | IC_kwDOBm6k_c5a4Ewj | simonw 9599 | 2023-04-27T03:56:42Z | 2023-04-27T03:57:11Z | OWNER | I don't have 3.7 locally. Trying to install it with `pyenv`. brew install pyenv Then: pyenv install --list | grep 3.7 Installing: pyenv install 3.7.16 Output: Installed Python-3.7.16 to /Users/simon/.pyenv/versions/3.7.16 So the executable is `/Users/simon/.pyenv/versions/3.7.16/bin/python`. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Failing test: httpx.InvalidURL: URL too long 1686042269 | |
1524655203 | https://github.com/simonw/datasette/issues/2066#issuecomment-1524655203 | https://api.github.com/repos/simonw/datasette/issues/2066 | IC_kwDOBm6k_c5a4GRj | simonw 9599 | 2023-04-27T03:59:56Z | 2023-04-27T03:59:56Z | OWNER | In a fresh Datasette checkout I ran: pipenv shell --python /Users/simon/.pyenv/versions/3.7.16/bin/python That gave me a virtual environment with 3.7.16 Python. Then I ran: pip install -e '.[test]' Weirdly that gave me a `which pytest` of `/opt/homebrew/bin/pytest` which ran the tests on 3.11. I figured out the location of the virtual environment with `which python` and then ran this: ``` % /Users/simon/.local/share/virtualenvs/datasette-cZYvnUqY/bin/pytest tests/test_csv.py ============================================================================================== test session starts =============================================================================================== platform darwin -- Python 3.7.16, pytest-7.3.1, pluggy-1.0.0 SQLite: 3.39.5 rootdir: /private/tmp/datasette configfile: pytest.ini plugins: asyncio-0.21.0, timeout-2.1.0, xdist-3.2.1, anyio-3.6.2 asyncio: mode=strict collected 15 items tests/test_csv.py ..........F.... [100%] ==================================================================================================== FAILURES ==================================================================================================== ________________________________________________________________________________________________ test_max_csv_mb _________________________________________________________________________________________________ app_client_csv_max_mb_one = <datasette.utils.testing.TestClient object at 0x107ab5c08> def test_max_csv_mb(app_client_csv_max_mb_one): response = app_client_csv_max_mb_one.get( ( "/fixtures.csv?sql=selec… | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Failing test: httpx.InvalidURL: URL too long 1686042269 | |
1524659084 | https://github.com/simonw/datasette/issues/2066#issuecomment-1524659084 | https://api.github.com/repos/simonw/datasette/issues/2066 | IC_kwDOBm6k_c5a4HOM | simonw 9599 | 2023-04-27T04:02:07Z | 2023-04-27T04:02:07Z | OWNER | This is the failing test: https://github.com/simonw/datasette/blob/249fcf8e3e2a90e763f41b080c1b9ec8017f5005/tests/test_csv.py#L156-L167 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Failing test: httpx.InvalidURL: URL too long 1686042269 | |
1524660603 | https://github.com/simonw/datasette/issues/2066#issuecomment-1524660603 | https://api.github.com/repos/simonw/datasette/issues/2066 | IC_kwDOBm6k_c5a4Hl7 | simonw 9599 | 2023-04-27T04:02:55Z | 2023-04-27T04:02:55Z | OWNER | In the debugger: ``` (Pdb) MAX_URL_LENGTH 65536 ``` Weird this only seems to be a problem with `httpx` on Python 3.7 though. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Failing test: httpx.InvalidURL: URL too long 1686042269 | |
1524666049 | https://github.com/simonw/datasette/issues/2066#issuecomment-1524666049 | https://api.github.com/repos/simonw/datasette/issues/2066 | IC_kwDOBm6k_c5a4I7B | simonw 9599 | 2023-04-27T04:06:18Z | 2023-04-27T04:06:18Z | OWNER | Most recent `httpx` release is 0.24 a couple of weeks ago. Here's what changed in that version: https://github.com/encode/httpx/compare/0.23.3...0.24.0 It looks like that URL limit is new: https://github.com/encode/httpx/commit/57daabf673705954afa94686c0002801c93d31f3#diff-78d8d93b5dd4c77d99c3e2b46b7286ba71a8fd60e92d8bd4eee5fb200b4f87bfR149-R155 ```python def urlparse(url: str = "", **kwargs: typing.Optional[str]) -> ParseResult: # Initial basic checks on allowable URLs. # --------------------------------------- # Hard limit the maximum allowable URL length. if len(url) > MAX_URL_LENGTH: raise InvalidURL("URL too long") ``` https://github.com/encode/httpx/blob/32e25497a36e6222cc64a758c98275b450dac28d/httpx/_urlparse.py#L153-L155 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Failing test: httpx.InvalidURL: URL too long 1686042269 | |
1524669124 | https://github.com/simonw/datasette/issues/2066#issuecomment-1524669124 | https://api.github.com/repos/simonw/datasette/issues/2066 | IC_kwDOBm6k_c5a4JrE | simonw 9599 | 2023-04-27T04:10:44Z | 2023-04-27T04:10:52Z | OWNER | I need an alternative way of generating a long string with a shorter URL. ```sql select group_concat('abcabcabc', '') from json_each(json_array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) ``` https://latest.datasette.io/_memory?sql=select+group_concat%28%27abcabcabc%27%2C+%27%27%29+from+json_each%28json_array%281%2C+2%2C+3%2C+4%2C+5%2C+6%2C+7%2C+8%2C+9%2C+10%29%29 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Failing test: httpx.InvalidURL: URL too long 1686042269 | |
1524675817 | https://github.com/simonw/datasette/issues/2066#issuecomment-1524675817 | https://api.github.com/repos/simonw/datasette/issues/2066 | IC_kwDOBm6k_c5a4LTp | simonw 9599 | 2023-04-27T04:21:03Z | 2023-04-27T04:21:03Z | OWNER | I went with this to generate the long string: https://github.com/simonw/datasette/blob/0b0c5cd7a94fe3f151a3e10261b5c84ee64f2f18/tests/test_csv.py#L157-L176 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Failing test: httpx.InvalidURL: URL too long 1686042269 | |
1524680160 | https://github.com/simonw/datasette/issues/2066#issuecomment-1524680160 | https://api.github.com/repos/simonw/datasette/issues/2066 | IC_kwDOBm6k_c5a4MXg | simonw 9599 | 2023-04-27T04:27:50Z | 2023-04-27T04:27:50Z | OWNER | That fixed it. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Failing test: httpx.InvalidURL: URL too long 1686042269 | |
1524616740 | https://github.com/simonw/datasette/issues/2065#issuecomment-1524616740 | https://api.github.com/repos/simonw/datasette/issues/2065 | IC_kwDOBm6k_c5a384k | simonw 9599 | 2023-04-27T03:38:21Z | 2023-04-27T03:38:21Z | OWNER | Tried this: rye install https://github.com/simonw/datasette/archive/refs/heads/main.zip But got this error: Error: Expected one of `@`, `(`, `<`, `=`, `>`, `~`, `!`, `;`, found `:` I instead downloaded that file and ran: rye install main.zip This worked! And now: ``` ~/.rye/tools/main-zip/bin/datasette --version ``` ``` datasette, version 1.0a2 ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Datasette cannot be installed with Rye 1686033652 | |
1524699863 | https://github.com/simonw/datasette/issues/2065#issuecomment-1524699863 | https://api.github.com/repos/simonw/datasette/issues/2065 | IC_kwDOBm6k_c5a4RLX | simonw 9599 | 2023-04-27T04:56:22Z | 2023-04-27T04:56:22Z | OWNER | Turned this into a TIL: https://til.simonwillison.net/python/rye | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Datasette cannot be installed with Rye 1686033652 | |
1524707628 | https://github.com/simonw/datasette/issues/2065#issuecomment-1524707628 | https://api.github.com/repos/simonw/datasette/issues/2065 | IC_kwDOBm6k_c5a4TEs | simonw 9599 | 2023-04-27T05:06:44Z | 2023-04-27T05:06:44Z | OWNER | I need `pip` as a dependency too: ``` % ~/.rye/tools/main-zip/bin/datasette install datasette-graphql Traceback (most recent call last): File "/Users/simon/.rye/tools/main-zip/bin/datasette", line 8, in <module> sys.exit(cli()) ^^^^^ File "/Users/simon/.rye/tools/main-zip/lib/python3.11/site-packages/click/core.py", line 1130, in __call__ return self.main(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/simon/.rye/tools/main-zip/lib/python3.11/site-packages/click/core.py", line 1055, in main rv = self.invoke(ctx) ^^^^^^^^^^^^^^^^ File "/Users/simon/.rye/tools/main-zip/lib/python3.11/site-packages/click/core.py", line 1657, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/simon/.rye/tools/main-zip/lib/python3.11/site-packages/click/core.py", line 1404, in invoke return ctx.invoke(self.callback, **ctx.params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/simon/.rye/tools/main-zip/lib/python3.11/site-packages/click/core.py", line 760, in invoke return __callback(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/simon/.rye/tools/main-zip/lib/python3.11/site-packages/datasette/cli.py", line 365, in install run_module("pip", run_name="__main__") File "<frozen runpy>", line 222, in run_module File "<frozen runpy>", line 142, in _get_module_details ImportError: No module named pip ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Datasette cannot be installed with Rye 1686033652 | |
1524709988 | https://github.com/simonw/datasette/issues/2065#issuecomment-1524709988 | https://api.github.com/repos/simonw/datasette/issues/2065 | IC_kwDOBm6k_c5a4Tpk | simonw 9599 | 2023-04-27T05:09:36Z | 2023-04-27T05:09:36Z | OWNER | That fixed it - after installing `main.zip` again I ran this and it worked: ~/.rye/tools/main-zip/bin/datasette install datasette-graphql ``` % ~/.rye/tools/main-zip/bin/datasette plugins [ { "name": "datasette-graphql", "static": true, "templates": true, "version": "2.2", "hooks": [ "database_actions", "extra_template_vars", "menu_links", "register_routes", "startup", "table_actions" ] } ] ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Datasette cannot be installed with Rye 1686033652 | |
1529737426 | https://github.com/simonw/datasette/pull/2064#issuecomment-1529737426 | https://api.github.com/repos/simonw/datasette/issues/2064 | IC_kwDOBm6k_c5bLfDS | dependabot[bot] 49699333 | 2023-05-01T13:58:50Z | 2023-05-01T13:58:50Z | CONTRIBUTOR | Superseded by #2068. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Bump sphinx from 6.1.3 to 6.2.1 1683229834 | |
1521837780 | https://github.com/simonw/datasette/pull/2063#issuecomment-1521837780 | https://api.github.com/repos/simonw/datasette/issues/2063 | IC_kwDOBm6k_c5atWbU | dependabot[bot] 49699333 | 2023-04-25T13:57:52Z | 2023-04-25T13:57:52Z | CONTRIBUTOR | Superseded by #2064. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Bump sphinx from 6.1.3 to 6.2.0 1681339696 | |
1506200813 | https://github.com/simonw/sqlite-utils/pull/537#issuecomment-1506200813 | https://api.github.com/repos/simonw/sqlite-utils/issues/537 | IC_kwDOCGYnMM5Zxszt | codecov[bot] 22429695 | 2023-04-13T01:45:22Z | 2023-04-13T01:45:22Z | NONE | ## [Codecov](https://codecov.io/gh/simonw/sqlite-utils/pull/537?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report Patch coverage: **`100.00`**% and no project coverage change. > Comparison is base [(`c0251cc`)](https://codecov.io/gh/simonw/sqlite-utils/commit/c0251cc9271260de73b4227859a51fab9b4cb745?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 96.25% compared to head [(`a75abeb`)](https://codecov.io/gh/simonw/sqlite-utils/pull/537?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 96.25%. <details><summary>Additional details and impacted files</summary> ```diff @@ Coverage Diff @@ ## main #537 +/- ## ======================================= Coverage 96.25% 96.25% ======================================= Files 6 6 Lines 2671 2673 +2 ======================================= + Hits 2571 2573 +2 Misses 100 100 ``` | [Impacted Files](https://codecov.io/gh/simonw/sqlite-utils/pull/537?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | | |---|---|---| | [sqlite\_utils/db.py](https://codecov.io/gh/simonw/sqlite-utils/pull/537?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-c3FsaXRlX3V0aWxzL2RiLnB5) | `97.33% <100.00%> (+<0.01%)` | :arrow_up: | 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&u… | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Support self-referencing FKs in `Table.create` 1665200812 | |
1539055393 | https://github.com/simonw/sqlite-utils/pull/537#issuecomment-1539055393 | https://api.github.com/repos/simonw/sqlite-utils/issues/537 | IC_kwDOCGYnMM5bvB8h | simonw 9599 | 2023-05-08T21:10:06Z | 2023-05-08T21:10:06Z | OWNER | Thanks! | {"total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Support self-referencing FKs in `Table.create` 1665200812 | |
1539157643 | https://github.com/simonw/sqlite-utils/pull/537#issuecomment-1539157643 | https://api.github.com/repos/simonw/sqlite-utils/issues/537 | IC_kwDOCGYnMM5bva6L | simonw 9599 | 2023-05-08T22:45:09Z | 2023-05-08T22:45:21Z | OWNER | Here's an example from the new tests: https://github.com/simonw/sqlite-utils/blob/a75abeb61b91a28650d3b9933e7ec80ad0d92529/tests/test_create.py#L291-L307 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Support self-referencing FKs in `Table.create` 1665200812 | |
1506174353 | https://github.com/simonw/datasette/issues/2059#issuecomment-1506174353 | https://api.github.com/repos/simonw/datasette/issues/2059 | IC_kwDOBm6k_c5ZxmWR | simonw 9599 | 2023-04-13T01:13:00Z | 2023-04-13T01:13:00Z | OWNER | Can you provide a URL to an example, and/or a screenshot of this? Is it a browser warning or is it a warning from Heroku itself? | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | "Deceptive site ahead" alert on Heroku deployment 1665053646 | |
1504291892 | https://github.com/simonw/datasette/issues/2058#issuecomment-1504291892 | https://api.github.com/repos/simonw/datasette/issues/2058 | IC_kwDOBm6k_c5Zqaw0 | simonw 9599 | 2023-04-11T23:58:45Z | 2023-04-11T23:58:45Z | OWNER | I thought it might relate to the "defensive mode" issue described here: - https://github.com/simonw/sqlite-utils/issues/235 But I have since determined that the Datasette official Docker image does NOT run anything in defensive mode, so I don't think it's related to that. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | 500 "attempt to write a readonly database" error caused by "PRAGMA schema_version" 1663399821 | |
1504292145 | https://github.com/simonw/datasette/issues/2058#issuecomment-1504292145 | https://api.github.com/repos/simonw/datasette/issues/2058 | IC_kwDOBm6k_c5Zqa0x | simonw 9599 | 2023-04-11T23:58:59Z | 2023-04-11T23:58:59Z | OWNER | Asked on the SQLite Forum if anyone has seen this before: https://sqlite.org/forum/forumpost/793a2ed75b | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | 500 "attempt to write a readonly database" error caused by "PRAGMA schema_version" 1663399821 | |
1504295345 | https://github.com/simonw/datasette/issues/2058#issuecomment-1504295345 | https://api.github.com/repos/simonw/datasette/issues/2058 | IC_kwDOBm6k_c5Zqbmx | simonw 9599 | 2023-04-12T00:01:42Z | 2023-04-12T00:02:26Z | OWNER | Here's the relevant code: https://github.com/simonw/datasette/blob/5890a20c374fb0812d88c9b0ef26a838bfa06c76/datasette/app.py#L421-L437 This function is called on almost every request (everything that subclasses `BaseView` at least - need to remember that for the refactor in #2053 etc). https://github.com/simonw/datasette/blob/5890a20c374fb0812d88c9b0ef26a838bfa06c76/datasette/views/base.py#L101-L103 It uses `PRAGMA schema_version` as a cheap way to determine if the schema has changed, in which case it needs to refresh the internal schema tables. This was already the cause of a subtle bug here: - #1231 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | 500 "attempt to write a readonly database" error caused by "PRAGMA schema_version" 1663399821 | |
1504298448 | https://github.com/simonw/datasette/issues/2058#issuecomment-1504298448 | https://api.github.com/repos/simonw/datasette/issues/2058 | IC_kwDOBm6k_c5ZqcXQ | simonw 9599 | 2023-04-12T00:04:01Z | 2023-04-12T00:04:01Z | OWNER | Here's a potential workaround: when I store the schema versions, I could also score an MD5 hash of the full schema (`select group_concat(sql) from sqlite_master`). When I read the schema version with `PRAGMA schema_version` I could catch that exception and, if I see it, I could calculate that MD5 hash again as a fallback and use that to determine if the schema has changed instead. The performance overhead of this needs investigating - how much more expensive is `md5(... that SQL query result)` compared to just `PRAGMA schema_version`, especially on a database with a lot of tables? | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | 500 "attempt to write a readonly database" error caused by "PRAGMA schema_version" 1663399821 | |
1504315697 | https://github.com/simonw/datasette/issues/2058#issuecomment-1504315697 | https://api.github.com/repos/simonw/datasette/issues/2058 | IC_kwDOBm6k_c5Zqgkx | simonw 9599 | 2023-04-12T00:16:22Z | 2023-04-12T00:27:12Z | OWNER | I got ChatGPT (code execution alpha) to run a micro-benchmark for me. This was the conclusion: > The benchmark using `PRAGMA schema_version` is approximately 1.36 times faster than the benchmark using `hashlib.md5` for the case with 100 tables. For the case with 200 tables, the benchmark using `PRAGMA schema_version` is approximately 2.33 times faster than the benchmark using `hashlib.md5`. Here's the chart it drew me: ![image](https://user-images.githubusercontent.com/9599/231315366-3a12b6d3-08d7-419d-a1fd-36eb24da0d85.png) (It's a pretty rubbish chart though, it only took measurements at 100 and 200 and drew a line between the two, I should have told it to measure every 10 and plot that) And the full transcript: https://gist.github.com/simonw/2fc46effbfbe49e6de0bcfdc9e31b235 The benchmark looks good enough on first glance that I don't feel the need to be more thorough with it. `PRAGMA schema_version` is faster, but not so fast that I feel like the MD5 hack is worth worrying about too much. I'm tempted to add something to the `/-/versions` page that tries to identify if this is a problem or not though. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | 500 "attempt to write a readonly database" error caused by "PRAGMA schema_version" 1663399821 | |
1504328395 | https://github.com/simonw/datasette/issues/2058#issuecomment-1504328395 | https://api.github.com/repos/simonw/datasette/issues/2058 | IC_kwDOBm6k_c5ZqjrL | simonw 9599 | 2023-04-12T00:28:38Z | 2023-04-12T00:28:38Z | OWNER | Here's a much better chart, which shows that MD5 performance unsurprisingly gets worse as the number of tables increases while `schema_version` remains constant: ![image](https://user-images.githubusercontent.com/9599/231316778-513bd99f-5ea4-495c-b86d-c572a7106369.png) | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | 500 "attempt to write a readonly database" error caused by "PRAGMA schema_version" 1663399821 | |
1504426792 | https://github.com/simonw/datasette/issues/2058#issuecomment-1504426792 | https://api.github.com/repos/simonw/datasette/issues/2058 | IC_kwDOBm6k_c5Zq7so | simonw 9599 | 2023-04-12T02:02:42Z | 2023-04-12T02:02:42Z | OWNER | I tightened up the benchmark (it was measuring the time taken to create the tables too) and got this: ![image](https://user-images.githubusercontent.com/9599/231328328-85ca35ac-a11b-46f4-b132-dae367103570.png) | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | 500 "attempt to write a readonly database" error caused by "PRAGMA schema_version" 1663399821 | |
1506203550 | https://github.com/simonw/datasette/issues/2058#issuecomment-1506203550 | https://api.github.com/repos/simonw/datasette/issues/2058 | IC_kwDOBm6k_c5Zxtee | cephillips 547438 | 2023-04-13T01:48:21Z | 2023-04-13T01:48:21Z | NONE | Really interesting how you are using ChatGPT in this. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | 500 "attempt to write a readonly database" error caused by "PRAGMA schema_version" 1663399821 | |
1507264934 | https://github.com/simonw/datasette/issues/2058#issuecomment-1507264934 | https://api.github.com/repos/simonw/datasette/issues/2058 | IC_kwDOBm6k_c5Z1wmm | esagara 1138559 | 2023-04-13T16:35:21Z | 2023-04-13T16:35:21Z | NONE | I tried deploying the fix you submitted, but still getting the same errors. I can past the logs here if needed, but I really don't see anything new in them. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | 500 "attempt to write a readonly database" error caused by "PRAGMA schema_version" 1663399821 | |
1503832422 | https://github.com/simonw/datasette/issues/2057#issuecomment-1503832422 | https://api.github.com/repos/simonw/datasette/issues/2057 | IC_kwDOBm6k_c5Zoqlm | simonw 9599 | 2023-04-11T17:42:57Z | 2023-04-11T17:46:42Z | OWNER | I ran this prompt against ChatGPT with the Browsing alpha: > ```python > if pkg_resources.resource_isdir(plugin.__name__, "static"): > static_path = pkg_resources.resource_filename( > plugin.__name__, "static" > ) > if pkg_resources.resource_isdir(plugin.__name__, "templates"): > templates_path = pkg_resources.resource_filename( > plugin.__name__, "templates" > ) > ``` > This code gives a deprecation warning in Python 3.11 - fix it It looked up the fix for me: <img width="632" alt="image" src="https://user-images.githubusercontent.com/9599/231245259-af4d962c-e631-420b-8312-fd9657a23bbd.png"> And suggested: ```python import importlib.resources # Replace pkg_resources.resource_isdir with importlib.resources.files().is_file() if importlib.resources.files(plugin.__name__).joinpath("static").is_file(): static_path = importlib.resources.as_file( importlib.resources.files(plugin.__name__).joinpath("static") ) if importlib.resources.files(plugin.__name__).joinpath("templates").is_file(): templates_path = importlib.resources.as_file( importlib.resources.files(plugin.__name__).joinpath("templates") ) ``` This looks wrong to me - I would expect something like `is_directory()` not `is_file()` for telling if `static/` is a directory. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | DeprecationWarning: pkg_resources is deprecated as an API 1662951875 | |
1503833906 | https://github.com/simonw/datasette/issues/2057#issuecomment-1503833906 | https://api.github.com/repos/simonw/datasette/issues/2057 | IC_kwDOBm6k_c5Zoq8y | simonw 9599 | 2023-04-11T17:44:16Z | 2023-04-11T17:45:45Z | OWNER | Another prompt: > How to fix this: > > `pkg_resources.get_distribution(package).version` Response: <img width="641" alt="image" src="https://user-images.githubusercontent.com/9599/231245559-dd943527-818a-45aa-9833-b9db8c7ca87e.png"> ```python import importlib.metadata # Get the version number of the specified package package_version = importlib.metadata.version(package) ``` That seems to work: ```pycon >>> import importlib.metadata >>> importlib.metadata.version("datasette") '0.64.2' >>> importlib.metadata.version("pluggy") '1.0.0' >>> importlib.metadata.version("not-a-package") ... importlib.metadata.PackageNotFoundError: No package metadata was found for not-a-package ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | DeprecationWarning: pkg_resources is deprecated as an API 1662951875 | |
1503838640 | https://github.com/simonw/datasette/issues/2057#issuecomment-1503838640 | https://api.github.com/repos/simonw/datasette/issues/2057 | IC_kwDOBm6k_c5ZosGw | simonw 9599 | 2023-04-11T17:48:23Z | 2023-04-11T17:48:23Z | OWNER | > This looks wrong to me - I would expect something like `is_directory()` not `is_file()` for telling if `static/` is a directory. I was right about that: ```pycon >>> importlib.resources.files('datasette_graphql') PosixPath('/Users/simon/.local/share/virtualenvs/datasette-big-local-6Yn-280V/lib/python3.11/site-packages/datasette_graphql') >>> importlib.resources.files('datasette_graphql').joinpath("static") PosixPath('/Users/simon/.local/share/virtualenvs/datasette-big-local-6Yn-280V/lib/python3.11/site-packages/datasette_graphql/static') >>> p = importlib.resources.files('datasette_graphql').joinpath("static") >>> p PosixPath('/Users/simon/.local/share/virtualenvs/datasette-big-local-6Yn-280V/lib/python3.11/site-packages/datasette_graphql/static') >>> p.is_ p.is_absolute() p.is_char_device() p.is_fifo() p.is_mount() p.is_reserved() p.is_symlink() p.is_block_device() p.is_dir() p.is_file() p.is_relative_to( p.is_socket() >>> p.is_dir() True >>> p.is_file() False ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | DeprecationWarning: pkg_resources is deprecated as an API 1662951875 | |
1506175208 | https://github.com/simonw/datasette/pull/2056#issuecomment-1506175208 | https://api.github.com/repos/simonw/datasette/issues/2056 | IC_kwDOBm6k_c5Zxmjo | simonw 9599 | 2023-04-13T01:14:13Z | 2023-04-13T01:14:13Z | OWNER | https://github.com/simonw/datasette/actions/runs/4664796647/jobs/8300596121?pr=2056 it's pretty fast - that finished in 9s. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | GitHub Action to lint Python code with ruff 1661860507 | |
1506177115 | https://github.com/simonw/datasette/pull/2056#issuecomment-1506177115 | https://api.github.com/repos/simonw/datasette/issues/2056 | IC_kwDOBm6k_c5ZxnBb | simonw 9599 | 2023-04-13T01:17:16Z | 2023-04-13T01:17:16Z | OWNER | Here are the failures: https://github.com/simonw/datasette/actions/runs/4684460653/jobs/8300630794?pr=2056 <img width="902" alt="CleanShot 2023-04-12 at 18 16 45@2x" src="https://user-images.githubusercontent.com/9599/231620533-bce286b7-8173-4a61-aac1-b772832fb893.png"> | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | GitHub Action to lint Python code with ruff 1661860507 | |
1506177857 | https://github.com/simonw/datasette/pull/2056#issuecomment-1506177857 | https://api.github.com/repos/simonw/datasette/issues/2056 | IC_kwDOBm6k_c5ZxnNB | simonw 9599 | 2023-04-13T01:18:18Z | 2023-04-13T01:18:18Z | OWNER | Cool - and now https://github.com/simonw/datasette/pull/2056/files is showing me those inline annotations: <img width="868" alt="image" src="https://user-images.githubusercontent.com/9599/231620660-4843d113-b671-494e-8265-24226446abba.png"> | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | GitHub Action to lint Python code with ruff 1661860507 | |
1506179555 | https://github.com/simonw/datasette/pull/2056#issuecomment-1506179555 | https://api.github.com/repos/simonw/datasette/issues/2056 | IC_kwDOBm6k_c5Zxnnj | simonw 9599 | 2023-04-13T01:21:05Z | 2023-04-13T01:22:08Z | OWNER | OK, I'm sold - this is a really neat improvement. One thing to change in the PR: right now it runs `pip install --user ruff` on every commit, which hits PyPI to install the package. I prefer to avoid hitting PyPI every time, so I like to use the GitHub Actions cache. My usual pattern for that looks like this: https://github.com/simonw/datasette/blob/5890a20c374fb0812d88c9b0ef26a838bfa06c76/.github/workflows/test-pyodide.yml#L16-L20 Then a separate command that runs `pip install ...` will benefit from that cache. Are you OK to make that change? | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | GitHub Action to lint Python code with ruff 1661860507 | |
1506485287 | https://github.com/simonw/datasette/pull/2056#issuecomment-1506485287 | https://api.github.com/repos/simonw/datasette/issues/2056 | IC_kwDOBm6k_c5ZyyQn | cclauss 3709715 | 2023-04-13T07:29:38Z | 2023-04-13T07:41:55Z | NONE | Ruff (written in Rust, not Python) is a 23MB executable so the time to download and pip install it dwarfs its runtime. Let's run ruff with and without GitHub Actions pip cache side-by-side to see the relative performance. Once you approve the workflows below, `ruff_with_cache` should echo `cache-hit = false` but if you rerun that job hopefully it should echo `cache-hit = true`. That will be the execution time that we are interested to compare. There are two great problems in computer science: ;-) 1. Naming things 2. Cache invalidation 3. Off-by-one errors For 2., https://github.com/actions/setup-python#caching-packages-dependencies is vital reading. Only _exactly pinned requirements_ can be cached. Currently in `setup.py` the only pinned dependencies are: 1. Sphinx==6.1.3 2. furo==2023.3.27 3. black==23.3.0 4. blacken-docs==1.13.0 # but unpinned elsewhere in `setup.py` This means that there will be very few cache hits in the current actions. See the link below to print out cache hits: https://github.com/actions/setup-python/blob/main/docs/advanced-usage.md#cache-hit > PyPI uses Fastly's CDN to quickly serve content to end-users, allowing us to minimize our hosting infrastructure and obscure possible downtime. -- https://pypi.org/sponsors I would be shocked if Fastly does not have beefy CDN nodes in the same datacenters where GitHub Actions run so GHA requests to download `ruff` probably never hit a PyPI server. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | GitHub Action to lint Python code with ruff 1661860507 | |
1509852821 | https://github.com/simonw/datasette/pull/2056#issuecomment-1509852821 | https://api.github.com/repos/simonw/datasette/issues/2056 | IC_kwDOBm6k_c5Z_oaV | cclauss 3709715 | 2023-04-15T14:24:45Z | 2023-04-15T14:24:45Z | NONE | Status? | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | GitHub Action to lint Python code with ruff 1661860507 | |
1500893216 | https://github.com/simonw/sqlite-utils/pull/536#issuecomment-1500893216 | https://api.github.com/repos/simonw/sqlite-utils/issues/536 | IC_kwDOCGYnMM5ZddAg | codecov[bot] 22429695 | 2023-04-08T13:35:42Z | 2023-04-08T13:35:42Z | NONE | ## [Codecov](https://codecov.io/gh/simonw/sqlite-utils/pull/536?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 [(`c0251cc`)](https://codecov.io/gh/simonw/sqlite-utils/commit/c0251cc9271260de73b4227859a51fab9b4cb745?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 96.25% compared to head [(`cea05dc`)](https://codecov.io/gh/simonw/sqlite-utils/pull/536?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 96.25%. <details><summary>Additional details and impacted files</summary> ```diff @@ Coverage Diff @@ ## main #536 +/- ## ======================================= Coverage 96.25% 96.25% ======================================= Files 6 6 Lines 2671 2671 ======================================= Hits 2571 2571 Misses 100 100 ``` | [Impacted Files](https://codecov.io/gh/simonw/sqlite-utils/pull/536?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | | |---|---|---| | [sqlite\_utils/utils.py](https://codecov.io/gh/simonw/sqlite-utils/pull/536?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-c3FsaXRlX3V0aWxzL3V0aWxzLnB5) | `95.13% <ø> (ø)` | | 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=Si… | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Add paths for homebrew on Apple silicon 1659525418 | |
1499452122 | https://github.com/simonw/datasette/issues/2054#issuecomment-1499452122 | https://api.github.com/repos/simonw/datasette/issues/2054 | IC_kwDOBm6k_c5ZX9La | simonw 9599 | 2023-04-06T18:21:51Z | 2023-04-06T18:21:51Z | OWNER | I'm going to make notes against the code in the most recent alpha release, ignoring the recent work I did to refactor `TableView`. https://github.com/simonw/datasette/tree/1.0a2/datasette/views | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Make detailed notes on how table, query and row views work right now 1657861026 | |
1499457201 | https://github.com/simonw/datasette/issues/2054#issuecomment-1499457201 | https://api.github.com/repos/simonw/datasette/issues/2054 | IC_kwDOBm6k_c5ZX-ax | simonw 9599 | 2023-04-06T18:26:39Z | 2023-04-06T18:26:39Z | OWNER | These classes - `TableView` and `RowView` and `QueryView` - all subclass `DataView` which subclasses` BaseView`. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Make detailed notes on how table, query and row views work right now 1657861026 | |
1499457291 | https://github.com/simonw/datasette/issues/2054#issuecomment-1499457291 | https://api.github.com/repos/simonw/datasette/issues/2054 | IC_kwDOBm6k_c5ZX-cL | simonw 9599 | 2023-04-06T18:26:45Z | 2023-04-06T18:26:45Z | OWNER | Here's `BaseView`: https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/base.py#L56-L145 It has methods for the `options`, `get`, `post`, `delete`, `put`, `patch` and `head` HTTP verbs, most defaulting to returinng a 405 Method not allowed message in plain text or JSON, depending on this check: https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/base.py#L71-L81 Also adds CORS headers to anything if CORS mode is on: https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/base.py#L106-L107 And adds the `database_color` (weirdly) and the `select_templates` variables to the template context: https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/base.py#L112-L122 And has special code for setting the `Link: ...; rel="alternate"` HTTP header: https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/base.py#L124-L136 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Make detailed notes on how table, query and row views work right now 1657861026 | |
1499462324 | https://github.com/simonw/datasette/issues/2054#issuecomment-1499462324 | https://api.github.com/repos/simonw/datasette/issues/2054 | IC_kwDOBm6k_c5ZX_q0 | simonw 9599 | 2023-04-06T18:31:56Z | 2023-04-06T18:31:56Z | OWNER | The `DataView` class does a LOT of work - mostly involving CSV responses. https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/base.py#L160-L544 It has a `redirect()` method with some complex logic and CORS handling: https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/base.py#L163-L172 It uses this method a lot, which has to be over-ridden in the `TableView` and `RowView` and `QueryView` subclasses: https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/base.py#L174-L175 This method: https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/base.py#L180 Is the bulk of the complexity, because it knows how to both turn a list of SQLite rows into a CSV file but also knows how to call `.data()` repeatedly with different pagination arguments in order to stream CSV back for a large table. The `async def get()` method for GET requests is also very complicated. It mainly handles format stuff - knowing how to render HTML v.s. JSON v.s. CSV v.s. other formats specified using this plugin hook: https://docs.datasette.io/en/1.0a2/plugin_hooks.html#register-output-renderer-datasette Plus it catches interrupted queries and returns a special error page for those (and other error messages too): https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/base.py#L381-L408 It adds the time taken to execute the queries: https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/base.py#L410-L411 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Make detailed notes on how table, query and row views work right now 1657861026 | |
1499465648 | https://github.com/simonw/datasette/issues/2054#issuecomment-1499465648 | https://api.github.com/repos/simonw/datasette/issues/2054 | IC_kwDOBm6k_c5ZYAew | simonw 9599 | 2023-04-06T18:35:03Z | 2023-04-06T18:35:03Z | OWNER | There are actually five classes that subclass `DataView`: https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/row.py#L16 https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/database.py#L34 https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/database.py#L172 https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/database.py#L215 https://github.com/simonw/datasette/blob/8b9d7fdbd8de7e74414cc29e3005382669a812dc/datasette/views/table.py#L72 I don't think `DatabaseView` and `DatabaseDownload` should have subclassed that at all, since they don't return a table of data. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Make detailed notes on how table, query and row views work right now 1657861026 | |
1499467703 | https://github.com/simonw/datasette/issues/2054#issuecomment-1499467703 | https://api.github.com/repos/simonw/datasette/issues/2054 | IC_kwDOBm6k_c5ZYA-3 | simonw 9599 | 2023-04-06T18:37:22Z | 2023-04-06T18:57:22Z | OWNER | I've been hoping to move entirely away from class-based views, but now I'm wondering if that's the right decision given the need to support HTTP verbs. It is cleaner to have a class that has methods for each verb, or to have a single function that can behave differently depending on the verb? Or should I have a mechanism for dispatching to separate functions based on the verbs that isn't implemented in a base class? The trouble with using base classes is that I've already shown that they tempt me to put logic in weird places, which makes code harder to modify later on. The thing here is that the ONLY thing I want to use the base class for is as an HTTP verb switcher - which makes me doubt that I should risk taking on the other temptations of having a base class. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Make detailed notes on how table, query and row views work right now 1657861026 | |
1499491258 | https://github.com/simonw/datasette/issues/2054#issuecomment-1499491258 | https://api.github.com/repos/simonw/datasette/issues/2054 | IC_kwDOBm6k_c5ZYGu6 | simonw 9599 | 2023-04-06T19:00:16Z | 2023-04-06T20:40:16Z | OWNER | I asked GPT-4 to compare URL routing based on path and verb approaches in different languages and frameworks and spit out some examples. Full transcript here: https://gist.github.com/simonw/fa2379b97420404a81b0fcdb4db79657 Initial prompt: > Show me code examples of different web frameworks in Python and JavaScript and Go illustrating how HTTP routing works - in particular the problem of mapping an incoming HTTP request to some code based on both the URL path and the HTTP verb > > Don't show installation instructions, just get straight to the code snippets Flask: ```python from flask import Flask app = Flask(__name__) @app.route('/example', methods=['GET']) def get_example(): return "This is a GET request." @app.route('/example', methods=['POST']) def post_example(): return "This is a POST request." if __name__ == '__main__': app.run() ``` Express: ```javascript const express = require('express'); const app = express(); app.get('/example', (req, res) => { res.send('This is a GET request.'); }); app.post('/example', (req, res) => { res.send('This is a POST request.'); }); app.listen(3000, () => { console.log('Server is running on port 3000'); }); ``` Gin: ```go package main import ( "github.com/gin-gonic/gin" ) func main() { r := gin.Default() r.GET("/example", func(c *gin.Context) { c.String(200, "This is a GET request.") }) r.POST("/example", func(c *gin.Context) { c.String(200, "This is a POST request.") }) r.Run() } ``` Actix-web: ```rust use actix_web::{web, App, HttpResponse, HttpServer, Responder}; async fn get_example() -> impl Responder { HttpResponse::Ok().body("This is a GET request.") } async fn post_example() -> impl Responder { HttpResponse::Ok().body("This is a POST request.") } #[actix_web::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| { App::new() .route("/example", web::get().to(get_example)) .route("/example… | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Make detailed notes on how table, query and row views work right now 1657861026 | |
1499530921 | https://github.com/simonw/datasette/issues/2054#issuecomment-1499530921 | https://api.github.com/repos/simonw/datasette/issues/2054 | IC_kwDOBm6k_c5ZYQap | simonw 9599 | 2023-04-06T19:41:52Z | 2023-04-06T19:42:09Z | OWNER | Turned this into a TIL: https://til.simonwillison.net/gpt3/gpt4-api-design | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Make detailed notes on how table, query and row views work right now 1657861026 | |
1499596941 | https://github.com/simonw/datasette/issues/2054#issuecomment-1499596941 | https://api.github.com/repos/simonw/datasette/issues/2054 | IC_kwDOBm6k_c5ZYgiN | simonw 9599 | 2023-04-06T20:39:35Z | 2023-04-06T20:39:35Z | OWNER | I think there are two main approaches: - Map path to a function, that function then behaves differently on GET/POST/etc - Map method AND path to a function - the `app.get('/example')` v.s. `app.post('/example')` ones The decorator approach is calling out to me a bit now. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Make detailed notes on how table, query and row views work right now 1657861026 | |
1499604066 | https://github.com/simonw/datasette/issues/2054#issuecomment-1499604066 | https://api.github.com/repos/simonw/datasette/issues/2054 | IC_kwDOBm6k_c5ZYiRi | simonw 9599 | 2023-04-06T20:47:30Z | 2023-04-06T20:47:30Z | OWNER | I'm contemplating a new approach: using a class with static methods. Something like this: ```python class TableView(MethodRouter): @staticmethod async def get(request): return Response.text("GET") @staticmethod async def post(request): return Response.text("POST") ``` So effectively the class is just there to bundle together verb implementations, and to provide a `route(request)` method which knows how to dispatch them to the right place. It can offer default HEAD and OPTIONS methods too. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Make detailed notes on how table, query and row views work right now 1657861026 | |
1499604822 | https://github.com/simonw/datasette/issues/2054#issuecomment-1499604822 | https://api.github.com/repos/simonw/datasette/issues/2054 | IC_kwDOBm6k_c5ZYidW | simonw 9599 | 2023-04-06T20:48:19Z | 2023-04-06T20:48:55Z | OWNER | I actually quite like that. I could even use `@classmethod` and have utility methods defined on that class that both `get()` and `post()` could call. The crucial rule here is NO INSTANCE STATE - that's what makes routing to classes particularly damaging, and encourages code that's hard to maintain. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Make detailed notes on how table, query and row views work right now 1657861026 | |
1499797384 | https://github.com/simonw/datasette/issues/2054#issuecomment-1499797384 | https://api.github.com/repos/simonw/datasette/issues/2054 | IC_kwDOBm6k_c5ZZReI | dsisnero 6213 | 2023-04-07T00:46:50Z | 2023-04-07T00:46:50Z | NONE | you should have a look at Roda written in ruby . | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Make detailed notes on how table, query and row views work right now 1657861026 | |
1500608101 | https://github.com/simonw/datasette/issues/2054#issuecomment-1500608101 | https://api.github.com/repos/simonw/datasette/issues/2054 | IC_kwDOBm6k_c5ZcXZl | simonw 9599 | 2023-04-07T20:14:38Z | 2023-04-07T20:14:38Z | OWNER | Ooh that one's really interesting - very different from the others: ```ruby # app.rb require "roda" class App < Roda route do |r| r.root do "Home page" end r.on "pages" do r.get ":slug" do |slug| "Page: #{slug}" end end r.on "news" do r.get ":yyyy/:mm/:dd" do |yyyy, mm, dd| "News for #{yyyy}/#{mm}/#{dd}" end end end end # config.ru require_relative "app" run App.freeze.app ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Make detailed notes on how table, query and row views work right now 1657861026 | |
1498279469 | https://github.com/simonw/datasette/pull/2053#issuecomment-1498279469 | https://api.github.com/repos/simonw/datasette/issues/2053 | IC_kwDOBm6k_c5ZTe4t | simonw 9599 | 2023-04-05T23:28:53Z | 2023-04-05T23:28:53Z | OWNER | Table errors page currently does this: ```json { "ok": false, "error": "no such column: blah", "status": 400, "title": "Invalid SQL" } ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | WIP new JSON for queries 1656432059 | |
1563285150 | https://github.com/simonw/datasette/pull/2053#issuecomment-1563285150 | https://api.github.com/repos/simonw/datasette/issues/2053 | IC_kwDOBm6k_c5dLdae | simonw 9599 | 2023-05-25T17:48:50Z | 2023-05-25T17:49:52Z | OWNER | Uncommitted experimental code: ```diff diff --git a/datasette/views/database.py b/datasette/views/database.py index 455ebd1f..85775433 100644 --- a/datasette/views/database.py +++ b/datasette/views/database.py @@ -909,12 +909,13 @@ async def query_view( elif format_ in datasette.renderers.keys(): # Dispatch request to the correct output format renderer # (CSV is not handled here due to streaming) + print(data) result = call_with_supported_arguments( datasette.renderers[format_][0], datasette=datasette, - columns=columns, - rows=rows, - sql=sql, + columns=data["rows"][0].keys(), + rows=data["rows"], + sql='', query_name=None, database=db.name, table=None, @@ -923,7 +924,7 @@ async def query_view( # These will be deprecated in Datasette 1.0: args=request.args, data={ - "rows": rows, + "rows": data["rows"], }, # TODO what should this be? ) result = await await_me_maybe(result) diff --git a/docs/index.rst b/docs/index.rst index 5a9cc7ed..254ed3da 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -57,6 +57,7 @@ Contents settings introspection custom_templates + template_context plugins writing_plugins plugin_hooks ``` Where `docs/template_context.rst` looked like this: ```rst .. _template_context: Template context ================ .. currentmodule:: datasette.context This page describes the variables made available to templates used by Datasette to render different pages of the application. .. autoclass:: QueryContext :members: ``` And `datasette/context.py` had this: ```python from dataclasses import dataclass @dataclass class QueryContext: """ Used by the ``/database`` page when showing the results of a SQL query """ id: int "… | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | WIP new JSON for queries 1656432059 | |
1563663616 | https://github.com/simonw/datasette/pull/2053#issuecomment-1563663616 | https://api.github.com/repos/simonw/datasette/issues/2053 | IC_kwDOBm6k_c5dM50A | simonw 9599 | 2023-05-26T00:32:08Z | 2023-05-26T00:32:08Z | OWNER | Now that I have the new `View` subclass from #2078 I want to use it to simplify this code. Challenge: there are several things to consider here: - The `/db` page without `?sql=` displays a list of tables in that database - With `?sql=` it shows the query results for that query (or an error) - If it's a `/db/name-of-canned-query` it works a bit like the query page, but executes a canned query instead of the `?sql=` query - POST `/db/name-of-canned-query` is support for writable canned queries | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | WIP new JSON for queries 1656432059 | |
1563663925 | https://github.com/simonw/datasette/pull/2053#issuecomment-1563663925 | https://api.github.com/repos/simonw/datasette/issues/2053 | IC_kwDOBm6k_c5dM541 | simonw 9599 | 2023-05-26T00:32:47Z | 2023-05-26T00:35:47Z | OWNER | I'm going to entirely split canned queries off from `?sql=` queries - they share a bunch of code right now which is just making everything much harder to follow. I'll refactor their shared bits into functions that they both call. Or _maybe_ I'll try having `CannedQueryView` as a subclass of `QueryView`. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | WIP new JSON for queries 1656432059 | |
1563667574 | https://github.com/simonw/datasette/pull/2053#issuecomment-1563667574 | https://api.github.com/repos/simonw/datasette/issues/2053 | IC_kwDOBm6k_c5dM6x2 | simonw 9599 | 2023-05-26T00:40:22Z | 2023-05-26T00:40:22Z | OWNER | Or maybe... - `BaseQueryView(View)` - knows how to render the results of a SQL query - `QueryView(BaseQueryView)` - renders from `?sql=` - `CannedQueryView(BaseQueryView)` - renders for a named canned query And then later perhaps: - `RowQueryView(BaseQueryView)` - renders the `select * from t where pk = ?` - `TableQueryView(BaseQueryView)` - replaces the super complex existing `TableView` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | WIP new JSON for queries 1656432059 | |
1563793781 | https://github.com/simonw/datasette/pull/2053#issuecomment-1563793781 | https://api.github.com/repos/simonw/datasette/issues/2053 | IC_kwDOBm6k_c5dNZl1 | simonw 9599 | 2023-05-26T04:27:55Z | 2023-05-26T04:27:55Z | OWNER | I should split out a `canned_query.html` template too, as something that extends the `query.html` template. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | WIP new JSON for queries 1656432059 | |
1565058994 | https://github.com/simonw/datasette/pull/2053#issuecomment-1565058994 | https://api.github.com/repos/simonw/datasette/issues/2053 | IC_kwDOBm6k_c5dSOey | simonw 9599 | 2023-05-26T23:13:02Z | 2023-05-26T23:13:02Z | OWNER | I should have an extra called `extra_html_context` which bundles together all of the weird extra stuff needed by the HTML template, and is then passed as the root context when the template is rendered (with the other stuff from extras patched into it). | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | WIP new JSON for queries 1656432059 | |
1592052320 | https://github.com/simonw/sqlite-utils/issues/535#issuecomment-1592052320 | https://api.github.com/repos/simonw/sqlite-utils/issues/535 | IC_kwDOCGYnMM5e5Mpg | chapmanjacobd 7908073 | 2023-06-14T22:05:28Z | 2023-06-14T22:05:28Z | CONTRIBUTOR | piping to `jq` is good enough usually | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | rows: --transpose or psql extended view-like functionality 1655860104 | |
1592617271 | https://github.com/simonw/sqlite-utils/issues/535#issuecomment-1592617271 | https://api.github.com/repos/simonw/sqlite-utils/issues/535 | IC_kwDOCGYnMM5e7Wk3 | erlend-aasland 13780613 | 2023-06-15T08:39:49Z | 2023-06-15T08:39:49Z | NONE | > piping to `jq` is good enough usually ... or `python -m json.tool`[^1], if you don't have `jq` installed. [^1]: no fancy colouring, like `jq`; only pretty-printing | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | rows: --transpose or psql extended view-like functionality 1655860104 | |
1509461324 | https://github.com/simonw/datasette/pull/2052#issuecomment-1509461324 | https://api.github.com/repos/simonw/datasette/issues/2052 | IC_kwDOBm6k_c5Z-I1M | hydrosquall 9020979 | 2023-04-15T01:57:06Z | 2023-04-15T01:57:06Z | NONE | Notes from 1:1 - it _is_ possible to pass in URL params into a ObservableHQ notebook: https://observablehq.com/@bherbertlc/pass-values-as-url-parameters | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | feat: Javascript Plugin API (Custom panels, column menu items with JS actions) 1651082214 |
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]);
updated_at (date) >30 ✖