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/1442#issuecomment-902235714 | https://api.github.com/repos/simonw/datasette/issues/1442 | 902235714 | IC_kwDOBm6k_c41xwZC | 9599 | 2021-08-19T20:50:38Z | 2021-08-19T20:50:38Z | OWNER | Would this allow anyone to push a PR to this repo that would result in their code being deployed against my Cloud Run account? I'm reasonably confident that it would not, since the secrets would not be visible to their PR branch. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
974987856 | |
https://github.com/simonw/datasette/issues/1442#issuecomment-902231018 | https://api.github.com/repos/simonw/datasette/issues/1442 | 902231018 | IC_kwDOBm6k_c41xvPq | 9599 | 2021-08-19T20:42:08Z | 2021-08-19T20:42:08Z | OWNER | If I get this working I should document it on https://docs.datasette.io/en/stable/contributing.html | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
974987856 | |
https://github.com/simonw/datasette/issues/1442#issuecomment-902217726 | https://api.github.com/repos/simonw/datasette/issues/1442 | 902217726 | IC_kwDOBm6k_c41xr_- | 9599 | 2021-08-19T20:21:47Z | 2021-08-19T20:21:47Z | OWNER | I think the neatest way to implement this would be for the `on -> push -> branches` list to be the list of branches that should be deployed in this way. The rest of the code can react to that. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
974987856 | |
https://github.com/simonw/datasette/issues/1442#issuecomment-902191150 | https://api.github.com/repos/simonw/datasette/issues/1442 | 902191150 | IC_kwDOBm6k_c41xlgu | 9599 | 2021-08-19T19:43:05Z | 2021-08-19T19:43:59Z | OWNER | Maybe as simple as teaching https://github.com/simonw/datasette/blob/main/.github/workflows/deploy-latest.yml to run on pushes to ALL branches: https://github.com/simonw/datasette/blob/adb5b70de5cec3c3dd37184defe606a082c232cf/.github/workflows/deploy-latest.yml#L3-L6 And then quit early if the branch is not in some allow-list. If it IS in the allow-list, use the name of the branch to dynamically construct the name of the Cloud Run service here: https://github.com/simonw/datasette/blob/adb5b70de5cec3c3dd37184defe606a082c232cf/.github/workflows/deploy-latest.yml#L60 Need to skip the documentation build and deployment stuff for other branches though. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
974987856 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-901475812 | https://api.github.com/repos/simonw/datasette/issues/1293 | 901475812 | IC_kwDOBm6k_c41u23k | 9599 | 2021-08-18T22:41:19Z | 2021-08-18T22:41:19Z | OWNER | > Maybe I split this out into a separate Python library that gets tested against _every_ SQLite release I can possibly try it against, and then bakes out the supported release versions into the library code itself? I'm going to do this, and call the Python library `sqlite-explain`. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/sqlite-utils/issues/37#issuecomment-901452199 | https://api.github.com/repos/simonw/sqlite-utils/issues/37 | 901452199 | IC_kwDOCGYnMM41uxGn | 9599 | 2021-08-18T21:48:57Z | 2021-08-18T21:48:57Z | OWNER | I did a bunch of work on this in #266. The library is now pretty thoroughly typed, and I even found a couple of bugs using `mypy` along the way: #313 and #315. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
465815372 | |
https://github.com/simonw/sqlite-utils/issues/318#issuecomment-901440752 | https://api.github.com/repos/simonw/sqlite-utils/issues/318 | 901440752 | IC_kwDOCGYnMM41uuTw | 9599 | 2021-08-18T21:25:30Z | 2021-08-18T21:25:30Z | OWNER | Some questions: - Should this support compression formats other than gzip? - Should `memory` learn to auto-detect gzipped data? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
974067156 | |
https://github.com/simonw/sqlite-utils/issues/318#issuecomment-901440207 | https://api.github.com/repos/simonw/sqlite-utils/issues/318 | 901440207 | IC_kwDOCGYnMM41uuLP | 9599 | 2021-08-18T21:24:28Z | 2021-08-18T21:24:49Z | OWNER | Something like this then: sqlite-utils file.db "select * from t" --csv --gz > t.csv.gz Maybe add a `-o t.csv.gz` option too so you don't have to use a `>`. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
974067156 | |
https://github.com/simonw/sqlite-utils/issues/295#issuecomment-901403298 | https://api.github.com/repos/simonw/sqlite-utils/issues/295 | 901403298 | IC_kwDOCGYnMM41ulKi | 9599 | 2021-08-18T20:19:04Z | 2021-08-18T20:19:04Z | OWNER | Thanks, this was a bug. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
934123448 | |
https://github.com/simonw/sqlite-utils/issues/296#issuecomment-901399139 | https://api.github.com/repos/simonw/sqlite-utils/issues/296 | 901399139 | IC_kwDOCGYnMM41ukJj | 9599 | 2021-08-18T20:12:34Z | 2021-08-18T20:13:12Z | OWNER | Documentation for `table.search(..., quote=True)`: https://sqlite-utils.datasette.io/en/latest/python-api.html#searching-with-table-search In the API reference: https://sqlite-utils.datasette.io/en/latest/reference.html#sqlite_utils.db.Table.search And for the CLI `--quote` option: https://sqlite-utils.datasette.io/en/latest/cli.html#executing-searches | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
944326512 | |
https://github.com/simonw/sqlite-utils/issues/296#issuecomment-901398216 | https://api.github.com/repos/simonw/sqlite-utils/issues/296 | 901398216 | IC_kwDOCGYnMM41uj7I | 9599 | 2021-08-18T20:11:01Z | 2021-08-18T20:11:01Z | OWNER | ``` % sqlite-utils search fixtures.db searchable 'dog"' Error: malformed MATCH expression: [dog"] Try running this again with the --quote option ``` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
944326512 | |
https://github.com/simonw/sqlite-utils/issues/296#issuecomment-901390635 | https://api.github.com/repos/simonw/sqlite-utils/issues/296 | 901390635 | IC_kwDOCGYnMM41uiEr | 9599 | 2021-08-18T19:58:53Z | 2021-08-18T19:58:53Z | OWNER | ``` sqlite-utils search fixtures.db searchable 'dog"' Error: malformed MATCH expression: [dog"] ``` This error message could suggest retrying with `--quote`. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
944326512 | |
https://github.com/simonw/sqlite-utils/issues/296#issuecomment-901379930 | https://api.github.com/repos/simonw/sqlite-utils/issues/296 | 901379930 | IC_kwDOCGYnMM41ufda | 9599 | 2021-08-18T19:40:38Z | 2021-08-18T19:40:38Z | OWNER | Also add `sqlite-utils search ... --quote` option. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
944326512 | |
https://github.com/simonw/sqlite-utils/issues/246#issuecomment-901353345 | https://api.github.com/repos/simonw/sqlite-utils/issues/246 | 901353345 | IC_kwDOCGYnMM41uY-B | 9599 | 2021-08-18T18:57:13Z | 2021-08-18T18:57:13Z | OWNER | More documentation: https://sqlite-utils.datasette.io/en/latest/python-api.html#quoting-characters-for-use-in-search | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
831751367 | |
https://github.com/simonw/sqlite-utils/issues/296#issuecomment-901338841 | https://api.github.com/repos/simonw/sqlite-utils/issues/296 | 901338841 | IC_kwDOCGYnMM41uVbZ | 9599 | 2021-08-18T18:33:26Z | 2021-08-18T18:45:12Z | OWNER | I think I'll do this as an optional `table.search(..., escape=True)` parameter. Actually I'll do `quote=True` for consistency with the new `db.quote_fts()` method. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
944326512 | |
https://github.com/simonw/sqlite-utils/issues/246#issuecomment-901345800 | https://api.github.com/repos/simonw/sqlite-utils/issues/246 | 901345800 | IC_kwDOCGYnMM41uXII | 9599 | 2021-08-18T18:44:48Z | 2021-08-18T18:44:48Z | OWNER | The `db.quote_fts(value)` method from #247 can now be used for this - documentation here: https://sqlite-utils.datasette.io/en/latest/reference.html#sqlite_utils.db.Database.quote_fts I'll be adding further improvements relating to this (a `table.search(q, quote=True)` parameter) in #296. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
831751367 | |
https://github.com/simonw/sqlite-utils/pull/247#issuecomment-901344634 | https://api.github.com/repos/simonw/sqlite-utils/issues/247 | 901344634 | IC_kwDOCGYnMM41uW16 | 22429695 | 2021-08-18T18:42:54Z | 2021-08-18T18:42:54Z | NONE | # [Codecov](https://codecov.io/gh/simonw/sqlite-utils/pull/247?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report > Merging [#247](https://codecov.io/gh/simonw/sqlite-utils/pull/247?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (af989af) into [main](https://codecov.io/gh/simonw/sqlite-utils/commit/1fe73c898b44695052f1a9ca832818d50cecf662?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (1fe73c8) will **decrease** coverage by `0.03%`. > The diff coverage is `85.71%`. [![Impacted file tree graph](https://codecov.io/gh/simonw/sqlite-utils/pull/247/graphs/tree.svg?width=650&height=150&src=pr&token=O0X3703L9P&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)](https://codecov.io/gh/simonw/sqlite-utils/pull/247?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) ```diff @@ Coverage Diff @@ ## main #247 +/- ## ========================================== - Coverage 96.28% 96.24% -0.04% ========================================== Files 5 5 Lines 2179 2186 +7 ========================================== + Hits 2098 2104 +6 - Misses 81 82 +1 ``` | [Impacted Files](https://codecov.io/gh/simonw/sqlite-utils/pull/247?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/247/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-c3FsaXRlX3V0aWxzL2RiLnB5) | `97.84% <85.71%> (-0.08%)` … | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
832687563 | |
https://github.com/simonw/sqlite-utils/pull/247#issuecomment-901338988 | https://api.github.com/repos/simonw/sqlite-utils/issues/247 | 901338988 | IC_kwDOCGYnMM41uVds | 9599 | 2021-08-18T18:33:39Z | 2021-08-18T18:33:39Z | OWNER | This was also requested in #296. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
832687563 | |
https://github.com/simonw/sqlite-utils/issues/296#issuecomment-901338356 | https://api.github.com/repos/simonw/sqlite-utils/issues/296 | 901338356 | IC_kwDOCGYnMM41uVT0 | 9599 | 2021-08-18T18:32:39Z | 2021-08-18T18:32:39Z | OWNER | This is a good call. I have a fix for this in Datasette but it's not in `sqlite-utils` yet: https://github.com/simonw/datasette/blob/adb5b70de5cec3c3dd37184defe606a082c232cf/datasette/utils/__init__.py#L824-L835 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
944326512 | |
https://github.com/simonw/sqlite-utils/issues/317#issuecomment-901337305 | https://api.github.com/repos/simonw/sqlite-utils/issues/317 | 901337305 | IC_kwDOCGYnMM41uVDZ | 9599 | 2021-08-18T18:30:59Z | 2021-08-18T18:30:59Z | OWNER | I'm just going to remove this - I added it when the library was mostly undocumented, but it has comprehensive documentation now. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
972827346 | |
https://github.com/simonw/datasette/issues/1439#issuecomment-900715375 | https://api.github.com/repos/simonw/datasette/issues/1439 | 900715375 | IC_kwDOBm6k_c41r9Nv | 9599 | 2021-08-18T00:15:28Z | 2021-08-18T00:15:28Z | OWNER | Maybe I should use `-/` to encode forward slashes too, to defend against any ASGI servers that might not implement `raw_path` correctly. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
973139047 | |
https://github.com/simonw/datasette/issues/1439#issuecomment-900714630 | https://api.github.com/repos/simonw/datasette/issues/1439 | 900714630 | IC_kwDOBm6k_c41r9CG | 9599 | 2021-08-18T00:13:33Z | 2021-08-18T00:13:33Z | OWNER | The documentation should definitely cover how table names become URLs, in case any third party code needs to be able to calculate this themselves. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
973139047 | |
https://github.com/simonw/datasette/issues/1439#issuecomment-900712981 | https://api.github.com/repos/simonw/datasette/issues/1439 | 900712981 | IC_kwDOBm6k_c41r8oV | 9599 | 2021-08-18T00:09:59Z | 2021-08-18T00:12:32Z | OWNER | So given the original examples, a table called `table.csv` would have the following URLs: - `/db/table-.csv` - the HTML version - `/db/table-.csv.csv` - the CSV version - `/db/table-.csv.json` - the JSON version And if for some horific reason you had a table with the name `/db/table-.csv.csv` (so `/db/` was the first part of the actual table name in SQLite) the URLs would look like this: - `/db/%2Fdb%2Ftable---.csv-.csv` - the HTML version - `/db/%2Fdb%2Ftable---.csv-.csv.csv` - the CSV version - `/db/%2Fdb%2Ftable---.csv-.csv.json` - the JSON version | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
973139047 | |
https://github.com/simonw/datasette/issues/1439#issuecomment-900711967 | https://api.github.com/repos/simonw/datasette/issues/1439 | 900711967 | IC_kwDOBm6k_c41r8Yf | 9599 | 2021-08-18T00:08:09Z | 2021-08-18T00:08:09Z | OWNER | Here's an alternative I just made up which I'm calling "dot dash" encoding: ```python def dot_dash_encode(s): return s.replace("-", "--").replace(".", "-.") def dot_dash_decode(s): return s.replace("-.", ".").replace("--", "-") ``` And some examples: ```python for example in ( "hello", "hello.csv", "hello-and-so-on.csv", "hello-.csv", "hello--and--so--on-.csv", "hello.csv.", "hello.csv.-", "hello.csv.--", ): print(example) print(dot_dash_encode(example)) print(example == dot_dash_decode(dot_dash_encode(example))) print() ``` Outputs: ``` hello hello True hello.csv hello-.csv True hello-and-so-on.csv hello--and--so--on-.csv True hello-.csv hello---.csv True hello--and--so--on-.csv hello----and----so----on---.csv True hello.csv. hello-.csv-. True hello.csv.- hello-.csv-.-- True hello.csv.-- hello-.csv-.---- True ``` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
973139047 | |
https://github.com/simonw/datasette/issues/1439#issuecomment-900709703 | https://api.github.com/repos/simonw/datasette/issues/1439 | 900709703 | IC_kwDOBm6k_c41r71H | 9599 | 2021-08-18T00:03:09Z | 2021-08-18T00:03:09Z | OWNER | But... what if I invent my own escaping scheme? I actually did this once before, in https://github.com/simonw/datasette/commit/9fdb47ca952b93b7b60adddb965ea6642b1ff523 - while I was working on porting Datasette to ASGI in https://github.com/simonw/datasette/issues/272#issuecomment-494192779 because ASGI didn't yet have the `raw_path` mechanism. I could bring that back - it looked like this: ``` "table/and/slashes" => "tableU+002FandU+002Fslashes" "~table" => "U+007Etable" "+bobcats!" => "U+002Bbobcats!" "U+007Etable" => "UU+002B007Etable" ``` But I didn't particularly like it - it was quite verbose. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
973139047 | |
https://github.com/simonw/datasette/issues/1439#issuecomment-900705226 | https://api.github.com/repos/simonw/datasette/issues/1439 | 900705226 | IC_kwDOBm6k_c41r6vK | 9599 | 2021-08-17T23:50:32Z | 2021-08-17T23:50:47Z | OWNER | An alternative solution would be to use some form of escaping for the characters that form the name of the table. The obvious way to do this would be URL-encoding - but it doesn't hold for `.` characters. The hex for that is `%2E` but watch what happens with that in a URL: ``` # Against Cloud Run: curl -s 'https://datasette.io/-/asgi-scope/foo/bar%2Fbaz%2E' | rg path 'path': '/-/asgi-scope/foo/bar/baz.', 'raw_path': b'/-/asgi-scope/foo/bar%2Fbaz.', 'root_path': '', # Against Vercel: curl -s 'https://til.simonwillison.net/-/asgi-scope/foo/bar%2Fbaz%2E' | rg path 'path': '/-/asgi-scope/foo/bar%2Fbaz%2E', 'raw_path': b'/-/asgi-scope/foo/bar%2Fbaz%2E', 'root_path': '', ``` Surprisingly in this case Vercel DOES keep it intact, but Cloud Run does not. It's still no good though: I need a solution that works on Vercel, Cloud Run and every other potential hosting provider too. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
973139047 | |
https://github.com/simonw/datasette/issues/1439#issuecomment-900699670 | https://api.github.com/repos/simonw/datasette/issues/1439 | 900699670 | IC_kwDOBm6k_c41r5YW | 9599 | 2021-08-17T23:34:23Z | 2021-08-17T23:34:23Z | OWNER | The challenge comes down to telling the difference between the following: - `/db/table` - an HTML table page - `/db/table.csv` - the CSV version of `/db/table` - `/db/table.csv` - no this one is actually a database table called `table.csv` - `/db/table.csv.csv` - the CSV version of `/db/table.csv` - `/db/table.csv.csv.csv` and so on... | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
973139047 | |
https://github.com/simonw/datasette/issues/1438#issuecomment-900690998 | https://api.github.com/repos/simonw/datasette/issues/1438 | 900690998 | IC_kwDOBm6k_c41r3Q2 | 9599 | 2021-08-17T23:11:16Z | 2021-08-17T23:12:25Z | OWNER | I have completely failed to replicate this initial bug - but it's still there on the `thesession.vercel.app` deployment (even though my own deployments to Vercel do not exhibit it). Here's a one-liner to replicate it against that deployment: `curl -s 'https://thesession.vercel.app/thesession?sql=select+*+from+tunes+where+name+like+%22%25wise+maid%25%22' | rg '.csv'` Whit outputs this: `<p class="export-links">This data as <a href="/thesession.json?sql=select * from tunes where name like "%wise maid%"">json</a>, <a href="/thesession.csv?sql=select * from tunes where name like "%wise maid%"&_size=max">CSV</a></p>` It looks like, rather than being URL-encoded, the original query string is somehow making it through to Jinja and then being auto-escaped there. The weird thing is that the equivalent query executed against my `til.simonwillison.net` Vercel instance does this: `curl -s 'https://til.simonwillison.net/fixtures?sql=select+*+from+searchable+where+text1+like+%22%25a%25%22' | rg '.csv'` `<p class="export-links">This data as <a href="/fixtures.json?sql=select%20*%20from%20searchable%20where%20text1%20like%20%22%25a%25%22">json</a>, <a href="/fixtures.csv?sql=select%20*%20from%20searchable%20where%20text1%20like%20%22%25a%25%22&_size=max">CSV</a></p>` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
972918533 | |
https://github.com/simonw/datasette/issues/1438#issuecomment-900681413 | https://api.github.com/repos/simonw/datasette/issues/1438 | 900681413 | IC_kwDOBm6k_c41r07F | 9599 | 2021-08-17T22:47:44Z | 2021-08-17T22:47:44Z | OWNER | I deployed another copy of `fixtures.db` on Vercel at https://til.simonwillison.net/fixtures so I can compare it with `fixtures.db` on Cloud Run at https://latest.datasette.io/fixtures | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
972918533 | |
https://github.com/simonw/datasette/issues/1438#issuecomment-900518343 | https://api.github.com/repos/simonw/datasette/issues/1438 | 900518343 | IC_kwDOBm6k_c41rNHH | 9599 | 2021-08-17T18:04:42Z | 2021-08-17T18:04:42Z | OWNER | Here's how `request.query_string` works: https://github.com/simonw/datasette/blob/adb5b70de5cec3c3dd37184defe606a082c232cf/datasette/utils/asgi.py#L86-L88 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
972918533 | |
https://github.com/simonw/datasette/issues/1438#issuecomment-900516826 | https://api.github.com/repos/simonw/datasette/issues/1438 | 900516826 | IC_kwDOBm6k_c41rMva | 9599 | 2021-08-17T18:02:27Z | 2021-08-17T18:02:27Z | OWNER | The key difference I can spot between Vercel and Cloud Run is that `+` in a query string gets converted to `%20` by Vercel before it gets to my app, but does not for Cloud Run: ``` # Vercel ~ % curl -s 'https://til.simonwillison.net/-/asgi-scope?sql=select+*+from+tunes+where+name+like+%22%25wise+maid%25%22%0D%0A' | rg 'query_string' -C 2 'method': 'GET', 'path': '/-/asgi-scope', 'query_string': b'sql=select%20*%20from%20tunes%20where%20name%20like%20%22%25' b'wise%20maid%25%22%0D%0A', 'raw_path': b'/-/asgi-scope', # Cloud Run ~ % curl -s 'https://latest-with-plugins.datasette.io/-/asgi-scope?sql=select+*+from+tunes+where+name+like+%22%25wise+maid%25%22%0D%0A' | rg 'query_string' -C 2 'method': 'GET', 'path': '/-/asgi-scope', 'query_string': b'sql=select+*+from+tunes+where+name+like+%22%25wise+maid%25%2' b'2%0D%0A', 'raw_path': b'/-/asgi-scope', ``` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
972918533 | |
https://github.com/simonw/datasette/issues/1438#issuecomment-900513267 | https://api.github.com/repos/simonw/datasette/issues/1438 | 900513267 | IC_kwDOBm6k_c41rL3z | 9599 | 2021-08-17T17:57:05Z | 2021-08-17T17:57:05Z | OWNER | I'm having trouble replicating this bug outside of Vercel. Against Cloud Run: view-source:https://latest.datasette.io/fixtures?sql=select+*+from+searchable+where+text1+like+%22%25cat%25%22 The HTML here is: ```html <p class="export-links">This data as <a href="/fixtures.json?sql=select+*+from+searchable+where+text1+like+%22%25cat%25%22">json</a>, ... <a href="/fixtures.csv?sql=select+*+from+searchable+where+text1+like+%22%25cat%25%22&_size=max">CSV</a> </p> ``` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
972918533 | |
https://github.com/simonw/datasette/issues/1438#issuecomment-900502364 | https://api.github.com/repos/simonw/datasette/issues/1438 | 900502364 | IC_kwDOBm6k_c41rJNc | 9599 | 2021-08-17T17:40:41Z | 2021-08-17T17:40:41Z | OWNER | Bug is likely in `path_with_format` itself: https://github.com/simonw/datasette/blob/adb5b70de5cec3c3dd37184defe606a082c232cf/datasette/utils/__init__.py#L710-L729 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
972918533 | |
https://github.com/simonw/datasette/issues/1438#issuecomment-900500824 | https://api.github.com/repos/simonw/datasette/issues/1438 | 900500824 | IC_kwDOBm6k_c41rI1Y | 9599 | 2021-08-17T17:38:16Z | 2021-08-17T17:38:16Z | OWNER | Relevant template code: https://github.com/simonw/datasette/blob/adb5b70de5cec3c3dd37184defe606a082c232cf/datasette/templates/query.html#L71 `renderers` comes from here: https://github.com/simonw/datasette/blob/2883098770fc66e50183b2b231edbde20848d4d6/datasette/views/base.py#L593-L608 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
972918533 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-899915829 | https://api.github.com/repos/simonw/datasette/issues/1293 | 899915829 | IC_kwDOBm6k_c41o6A1 | 9599 | 2021-08-17T01:02:35Z | 2021-08-17T01:02:35Z | OWNER | New approach: this time I'm building a simplified executor for the bytecode operations themselves. ```python def execute_operations(operations, max_iterations = 100, trace=None): trace = trace or (lambda *args: None) registers: Dict[int, Any] = {} cursors: Dict[int, Tuple[str, Dict]] = {} instruction_pointer = 0 iterations = 0 result_row = None while True: iterations += 1 if iterations > max_iterations: break operation = operations[instruction_pointer] trace(instruction_pointer, dict(operation)) opcode = operation["opcode"] if opcode == "Init": if operation["p2"] != 0: instruction_pointer = operation["p2"] continue else: instruction_pointer += 1 continue elif opcode == "Goto": instruction_pointer = operation["p2"] continue elif opcode == "Halt": break elif opcode == "OpenRead": cursors[operation["p1"]] = ("database_table", { "rootpage": operation["p2"], "connection": operation["p3"], }) elif opcode == "OpenEphemeral": cursors[operation["p1"]] = ("ephemeral", { "num_columns": operation["p2"], "index_keys": [], }) elif opcode == "MakeRecord": registers[operation["p3"]] = ("MakeRecord", { "registers": list(range(operation["p1"] + operation["p2"])) }) elif opcode == "IdxInsert": record = registers[operation["p2"]] cursors[operation["p1"]][1]["index_keys"].append(record) elif opcode == "Rowid": registers[operation["p2"]] = ("rowid", { "table": operation["p1"] }) elif opcode == "Sequence": registers[operation["p2"]] = ("sequence", { "next_from_cursor": operat… | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1423#issuecomment-899749881 | https://api.github.com/repos/simonw/datasette/issues/1423 | 899749881 | IC_kwDOBm6k_c41oRf5 | 9599 | 2021-08-16T19:07:02Z | 2021-08-16T19:07:02Z | OWNER | Demo: https://latest.datasette.io/fixtures/compound_three_primary_keys?_facet=content&_facet_size=max&_facet=pk1&_facet=pk2 <img width="686" alt="fixtures__compound_three_primary_keys__1_001_rows" src="https://user-images.githubusercontent.com/9599/129616596-cc51b668-7cb8-482f-9e20-e0d8ca4b71be.png"> | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
962391325 | |
https://github.com/simonw/datasette/issues/1423#issuecomment-899744109 | https://api.github.com/repos/simonw/datasette/issues/1423 | 899744109 | IC_kwDOBm6k_c41oQFt | 9599 | 2021-08-16T18:58:29Z | 2021-08-16T18:58:29Z | OWNER | I didn't bother with the tooltip, just the visible display if `?_facet_size=max`. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
962391325 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898961535 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898961535 | IC_kwDOBm6k_c41lRB_ | 9599 | 2021-08-14T21:37:24Z | 2021-08-14T21:37:24Z | OWNER | Did some more research into building SQLite custom versions via `pysqlite3` - here's what I figured out for macOS (which should hopefully work for Linux too): https://til.simonwillison.net/sqlite/build-specific-sqlite-pysqlite-macos | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898936068 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898936068 | IC_kwDOBm6k_c41lK0E | 9599 | 2021-08-14T17:44:54Z | 2021-08-14T17:44:54Z | OWNER | Another interesting query to consider: https://latest.datasette.io/fixtures?sql=explain+select+*+from++pragma_table_info%28+%27123_starts_with_digits%27%29 That one shows `VColumn` instead of `Column`. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898933865 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898933865 | IC_kwDOBm6k_c41lKRp | 9599 | 2021-08-14T17:27:16Z | 2021-08-14T17:28:29Z | OWNER | Maybe I split this out into a separate Python library that gets tested against *every* SQLite release I can possibly try it against, and then bakes out the supported release versions into the library code itself? Datasette could depend on that library. The library could be released independently of Datasette any time a new SQLite version comes out. I could even run a separate git scraper repo that checks for new SQLite releases and submits PRs against the library when a new release comes out. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898913629 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898913629 | IC_kwDOBm6k_c41lFVd | 9599 | 2021-08-14T16:14:12Z | 2021-08-14T16:14:12Z | OWNER | I would feel a lot more comfortable about all of this if I had a robust mechanism for running the Datasette test suite against multiple versions of SQLite itself. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898913554 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898913554 | IC_kwDOBm6k_c41lFUS | 9599 | 2021-08-14T16:13:40Z | 2021-08-14T16:13:40Z | OWNER | I think I need to care about the following: - `ResultRow` and `Column` for the final result - `OpenRead` for opening tables - `OpenEphemeral` then `MakeRecord` and `IdxInsert` for writing records into ephemeral tables `Column` may reference either a table (from `OpenRead`) or an ephemeral table (from `OpenEphemeral`). That *might* be enough. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/sqlite-utils/issues/316#issuecomment-898824020 | https://api.github.com/repos/simonw/sqlite-utils/issues/316 | 898824020 | IC_kwDOCGYnMM41kvdU | 9599 | 2021-08-14T05:12:23Z | 2021-08-14T05:12:23Z | OWNER | No visible backticks on https://sqlite-utils.datasette.io/en/latest/reference.html any more. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
970320615 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898788262 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898788262 | IC_kwDOBm6k_c41kmum | 9599 | 2021-08-14T01:22:26Z | 2021-08-14T01:51:08Z | OWNER | Tried a more complicated query: ```sql explain select pk, text1, text2, [name with . and spaces] from searchable where rowid in (select rowid from searchable_fts where searchable_fts match escape_fts(:search)) order by text1 desc limit 101 ``` Here's the explain: ``` sqlite> explain select pk, text1, text2, [name with . and spaces] from searchable where rowid in (select rowid from searchable_fts where searchable_fts match escape_fts(:search)) order by text1 desc limit 101 ...> ; addr opcode p1 p2 p3 p4 p5 comment ---- ------------- ---- ---- ---- ------------- -- ------------- 0 Init 0 41 0 00 Start at 41 1 OpenEphemeral 2 6 0 k(1,-B) 00 nColumn=6 2 Integer 101 1 0 00 r[1]=101; LIMIT counter 3 OpenRead 0 32 0 4 00 root=32 iDb=0; searchable 4 Integer 16 3 0 00 r[3]=16; return address 5 Once 0 16 0 00 6 OpenEphemeral 3 1 0 k(1,) 00 nColumn=1; Result of SELECT 1 7 VOpen 1 0 0 vtab:7FCBCA72BE80 00 8 Function0 1 7 6 unknown(-1) 01 r[6]=func(r[7]) 9 Integer 5 4 0 00 r[4]=5 10 Integer 1 5 0 00 r[5]=1 11 VFilter 1 16 4 00 iplan=r[4] zplan='' 12 Rowid 1 8 0 00 r[8]=rowid 13 MakeRecord 8 1 9 C 00 r[9]=mkrec(r[8]) 14 IdxInsert 3 9 8 1 00 key=r[9] 15 VNext 1 12 0 00 16 Return 3 0 0 00 17 Rewind 3 33 0 00 18 Column 3… | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898760808 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898760808 | IC_kwDOBm6k_c41kgBo | 9599 | 2021-08-13T23:03:01Z | 2021-08-13T23:03:01Z | OWNER | Another idea: strip out any `order by` clause to try and keep this simpler. I doubt that's going to cope with complex nested queries though. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898760020 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898760020 | IC_kwDOBm6k_c41kf1U | 9599 | 2021-08-13T23:00:28Z | 2021-08-13T23:01:27Z | OWNER | New theory: this is all about `SorterOpen` and `SorterInsert`. Consider the following with extra annotations at the end of the lines after the `--`: ``` addr opcode p1 p2 p3 p4 p5 comment ---- ------------- ---- ---- ---- ------------- -- ------------- 0 Init 0 25 0 00 Start at 25 1 SorterOpen 2 5 0 k(1,B) 00 -- New SORTER in r2 with 5 slots 2 OpenRead 0 43 0 7 00 root=43 iDb=0; facetable 3 OpenRead 1 42 0 2 00 root=42 iDb=0; facet_cities 4 Rewind 0 16 0 00 5 Column 0 6 3 00 r[3]=facetable.neighborhood 6 Function0 1 2 1 like(2) 02 r[1]=func(r[2..3]) 7 IfNot 1 15 1 00 8 Column 0 5 4 00 r[4]=facetable.city_id 9 SeekRowid 1 15 4 00 intkey=r[4] 10 Column 1 1 6 00 r[6]=facet_cities.name 11 Column 0 4 7 00 r[7]=facetable.state 12 Column 0 6 5 00 r[5]=facetable.neighborhood 13 MakeRecord 5 3 9 00 r[9]=mkrec(r[5..7]) 14 SorterInsert 2 9 5 3 00 key=r[9]-- WRITES record from r9 (line above) into sorter in r2 15 Next 0 5 0 01 16 OpenPseudo 3 10 5 00 5 columns in r[10] 17 SorterSort 2 24 0 00 -- runs the sort, not relevant to my goal 18 SorterData 2 10 3 00 r[10]=data -- "Write into register P2 (r10) the current sorter data for sorter cursor P1 (sorter 2)" 19 Column 3 2 8 … | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898576097 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898576097 | IC_kwDOBm6k_c41jy7h | 9599 | 2021-08-13T16:19:57Z | 2021-08-13T16:19:57Z | OWNER | I think I need to look out for `OpenPseudo` and, when that occurs, take a look at the most recent `SorterInsert` and use that to find the `MakeRecord` and then use the `MakeRecord` to figure out the columns that went into it. After all of that I'll be able to resolve that "table 3" reference. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898572065 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898572065 | IC_kwDOBm6k_c41jx8h | 9599 | 2021-08-13T16:13:16Z | 2021-08-13T16:13:16Z | OWNER | Aha! That `MakeRecord` line says `r[5..7]` - and r5 = neighborhood, r6 = facet_cities.name, r7 = facetable.state So if the `MakeRecord` defines what goes into that pseudo-table column 2 of that pseudo-table would be `state` - which is what we want. This is really convoluted. I'm no longer confident I can get this to work in a sensible way, especially since I've not started exploring what complex nested tables with CTEs and sub-selects do yet. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898569319 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898569319 | IC_kwDOBm6k_c41jxRn | 9599 | 2021-08-13T16:09:01Z | 2021-08-13T16:10:48Z | OWNER | Need to figure out what column 2 of that pseudo-table is. I think the answer is here: ``` 4 Rewind 0 16 0 00 5 Column 0 6 3 00 r[3]=facetable.neighborhood 6 Function0 1 2 1 like(2) 02 r[1]=func(r[2..3]) 7 IfNot 1 15 1 00 8 Column 0 5 4 00 r[4]=facetable.city_id 9 SeekRowid 1 15 4 00 intkey=r[4] 10 Column 1 1 6 00 r[6]=facet_cities.name 11 Column 0 4 7 00 r[7]=facetable.state 12 Column 0 6 5 00 r[5]=facetable.neighborhood 13 MakeRecord 5 3 9 00 r[9]=mkrec(r[5..7]) 14 SorterInsert 2 9 5 3 00 key=r[9] 15 Next 0 5 0 01 16 OpenPseudo 3 10 5 00 5 columns in r[10] ``` I think the `OpenPseduo` line puts five columns in `r[10]` - and those five columns are the five from the previous block - maybe the five leading up to the `MakeRecord` call on line 13. In which case column 2 would be `facet_cities.name` - assuming we start counting from 0. But the debug code said "r[8]=state". | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898567974 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898567974 | IC_kwDOBm6k_c41jw8m | 9599 | 2021-08-13T16:07:00Z | 2021-08-13T16:07:00Z | OWNER | So this line: ``` 19 Column 3 2 8 00 r[8]=state ``` Means "Take column 2 of table 3 (the pseudo-table) and store it in register 8" | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898564705 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898564705 | IC_kwDOBm6k_c41jwJh | 9599 | 2021-08-13T16:02:12Z | 2021-08-13T16:04:06Z | OWNER | More debug output: ``` table_rootpage_by_register={0: 43, 1: 42} names_and_types_by_rootpage={42: ('facet_cities', 'table'), 43: ('facetable', 'table')} table_id=0 cid=6 column_register=3 table_id=0 cid=5 column_register=4 table_id=1 cid=1 column_register=6 table_id=0 cid=4 column_register=7 table_id=0 cid=6 column_register=5 table_id=3 cid=2 column_register=8 table_id=3 cid=2 column_register=8 KeyError 3 table = names_and_types_by_rootpage[table_rootpage_by_register[table_id]][0] names_and_types_by_rootpage={42: ('facet_cities', 'table'), 43: ('facetable', 'table')} table_rootpage_by_register={0: 43, 1: 42} table_id=3 columns_by_column_register[column_register] = (table, cid) column_register=8 = (table='facetable', cid=2) table_id=3 cid=1 column_register=7 KeyError 3 table = names_and_types_by_rootpage[table_rootpage_by_register[table_id]][0] names_and_types_by_rootpage={42: ('facet_cities', 'table'), 43: ('facetable', 'table')} table_rootpage_by_register={0: 43, 1: 42} table_id=3 columns_by_column_register[column_register] = (table, cid) column_register=7 = (table='facetable', cid=1) table_id=3 cid=0 column_register=6 KeyError 3 table = names_and_types_by_rootpage[table_rootpage_by_register[table_id]][0] names_and_types_by_rootpage={42: ('facet_cities', 'table'), 43: ('facetable', 'table')} table_rootpage_by_register={0: 43, 1: 42} table_id=3 columns_by_column_register[column_register] = (table, cid) column_register=6 = (table='facetable', cid=0) result_registers=[6, 7, 8] columns_by_column_register={3: ('facetable', 6), 4: ('facetable', 5), 6: ('facet_cities', 1), 7: ('facetable', 4), 5: ('facetable', 6)} all_column_names={('facet_cities', 0): 'id', ('facet_cities', 1): 'name', ('facetable', 0): 'pk', ('facetable', 1): 'created', ('facetable', 2): 'planet_int', ('facetable', 3): 'on_earth', ('facetable', 4): 'state', ('facetable', 5): 'city_id', ('facetable', 6): 'neighborhood', ('facetable', 7): 'tags', ('faceta… | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898554859 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898554859 | IC_kwDOBm6k_c41jtvr | 9599 | 2021-08-13T15:46:18Z | 2021-08-13T15:46:18Z | OWNER | So it looks like the bug is in the code that populates `columns_by_column_register`. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898554427 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898554427 | IC_kwDOBm6k_c41jto7 | 9599 | 2021-08-13T15:45:32Z | 2021-08-13T15:45:32Z | OWNER | Some useful debug output: ``` table_rootpage_by_register={0: 43, 1: 42} names_and_types_by_rootpage={42: ('facet_cities', 'table'), 43: ('facetable', 'table')} result_registers=[6, 7, 8] columns_by_column_register={3: ('facetable', 6), 4: ('facetable', 5), 6: ('facet_cities', 1), 7: ('facetable', 4), 5: ('facetable', 6)} all_column_names={('facet_cities', 0): 'id', ('facet_cities', 1): 'name', ('facetable', 0): 'pk', ('facetable', 1): 'created', ('facetable', 2): 'planet_int', ('facetable', 3): 'on_earth', ('facetable', 4): 'state', ('facetable', 5): 'city_id', ('facetable', 6): 'neighborhood', ('facetable', 7): 'tags', ('facetable', 8): 'complex_array', ('facetable', 9): 'distinct_some_null'} ``` The `result_registers` should each correspond to the correct entry in `columns_by_column_register` but they do not. Python code: ```python def columns_for_query(conn, sql, params=None): """ Given a SQLite connection ``conn`` and a SQL query ``sql``, returns a list of ``(table_name, column_name)`` pairs corresponding to the columns that would be returned by that SQL query. Each pair indicates the source table and column for the returned column, or ``(None, None)`` if no table and column could be derived (e.g. for "select 1") """ if sql.lower().strip().startswith("explain"): return [] opcodes = conn.execute("explain " + sql, params).fetchall() table_rootpage_by_register = { r["p1"]: r["p2"] for r in opcodes if r["opcode"] == "OpenRead" } print(f"{table_rootpage_by_register=}") names_and_types_by_rootpage = dict( [(r[0], (r[1], r[2])) for r in conn.execute( "select rootpage, name, type from sqlite_master where rootpage in ({})".format( ", ".join(map(str, table_rootpage_by_register.values())) ) )] ) print(f"{names_and_types_by_rootpage=}") columns_by_column_register = {} for opcode in opcodes: if opcode["opcode"] in ("Rowid", "Column"): … | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898545815 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898545815 | IC_kwDOBm6k_c41jriX | 9599 | 2021-08-13T15:31:53Z | 2021-08-13T15:31:53Z | OWNER | My hunch here is that registers or columns are being reused in a way that makes my code break - my code is pretty dumb, there are places in it where maybe the first mention of a register wins instead of the last one? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898541972 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898541972 | IC_kwDOBm6k_c41jqmU | 9599 | 2021-08-13T15:26:06Z | 2021-08-13T15:29:06Z | OWNER | ResultRow: > The registers P1 through P1+P2-1 contain a single row of results. This opcode causes the sqlite3_step() call to terminate with an SQLITE_ROW return code and it sets up the sqlite3_stmt structure to provide access to the r(P1)..r(P1+P2-1) values as the result row. Column: > Interpret the data that cursor P1 points to as a structure built using the MakeRecord instruction. (See the MakeRecord opcode for additional information about the format of the data.) Extract the P2-th column from this record. If there are less that (P2+1) values in the record, extract a NULL. > > The value extracted is stored in register P3. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898541543 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898541543 | IC_kwDOBm6k_c41jqfn | 9599 | 2021-08-13T15:25:26Z | 2021-08-13T15:25:26Z | OWNER | But the debug output here seems to be saying what we want it to say: ``` 17 SorterSort 2 24 0 00 18 SorterData 2 10 3 00 r[10]=data 19 Column 3 2 8 00 r[8]=state 20 Column 3 1 7 00 r[7]=facet_cities.name 21 Column 3 0 6 00 r[6]=neighborhood 22 ResultRow 6 3 0 00 output=r[6..8] ``` We want to get back `neighborhood`, `facet_cities.name`, `state`. Why then are we seeing `[('facet_cities', 'name'), ('facetable', 'state'), (None, None)]`? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898540260 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898540260 | IC_kwDOBm6k_c41jqLk | 9599 | 2021-08-13T15:23:28Z | 2021-08-13T15:23:28Z | OWNER | SorterInsert: > Register P2 holds an SQL index key made using the MakeRecord instructions. This opcode writes that key into the sorter P1. Data for the entry is nil. SorterData: > Write into register P2 the current sorter data for sorter cursor P1. Then clear the column header cache on cursor P3. > > This opcode is normally use to move a record out of the sorter and into a register that is the source for a pseudo-table cursor created using OpenPseudo. That pseudo-table cursor is the one that is identified by parameter P3. Clearing the P3 column cache as part of this opcode saves us from having to issue a separate NullRow instruction to clear that cache. OpenPseudo: > Open a new cursor that points to a fake table that contains a single row of data. The content of that one row is the content of memory register P2. In other words, cursor P1 becomes an alias for the MEM_Blob content contained in register P2. > > A pseudo-table created by this opcode is used to hold a single row output from the sorter so that the row can be decomposed into individual columns using the Column opcode. The Column opcode is the only cursor opcode that works with a pseudo-table. > > P3 is the number of fields in the records that will be stored by the pseudo-table. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898536181 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898536181 | IC_kwDOBm6k_c41jpL1 | 9599 | 2021-08-13T15:17:20Z | 2021-08-13T15:20:33Z | OWNER | Documentation for `MakeRecord`: https://www.sqlite.org/opcode.html#MakeRecord Running `explain` inside `sqlite3` provides extra comments and indentation which make it easier to understand: ``` sqlite> explain select neighborhood, facet_cities.name, state ...> from facetable ...> join facet_cities ...> on facetable.city_id = facet_cities.id ...> where neighborhood like '%bob%'; addr opcode p1 p2 p3 p4 p5 comment ---- ------------- ---- ---- ---- ------------- -- ------------- 0 Init 0 15 0 00 Start at 15 1 OpenRead 0 43 0 7 00 root=43 iDb=0; facetable 2 OpenRead 1 42 0 2 00 root=42 iDb=0; facet_cities 3 Rewind 0 14 0 00 4 Column 0 6 3 00 r[3]=facetable.neighborhood 5 Function0 1 2 1 like(2) 02 r[1]=func(r[2..3]) 6 IfNot 1 13 1 00 7 Column 0 5 4 00 r[4]=facetable.city_id 8 SeekRowid 1 13 4 00 intkey=r[4] 9 Column 0 6 5 00 r[5]=facetable.neighborhood 10 Column 1 1 6 00 r[6]=facet_cities.name 11 Column 0 4 7 00 r[7]=facetable.state 12 ResultRow 5 3 0 00 output=r[5..7] 13 Next 0 4 0 01 14 Halt 0 0 0 00 15 Transaction 0 0 35 0 01 usesStmtJournal=0 16 String8 0 2 0 %bob% 00 r[2]='%bob%' 17 Goto 0 1 0 00 ``` Compared with: ``` sqlite> explain select neighborhood, facet… | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898527525 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898527525 | IC_kwDOBm6k_c41jnEl | 9599 | 2021-08-13T15:08:03Z | 2021-08-13T15:08:03Z | OWNER | Am I going to need to look at the `ResultRow` and its columns but then wind back to that earlier `MakeRecord` and its columns? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898524057 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898524057 | IC_kwDOBm6k_c41jmOZ | 9599 | 2021-08-13T15:06:37Z | 2021-08-13T15:06:37Z | OWNER | Comparing the `explain` for the two versions of that query - one with the order by and one without: <img width="1031" alt="fixtures__explain_select_neighborhood__facet_cities_name__state_from_facetable_join_facet_cities_on_facetable_city_id___facet_cities_id_where_neighborhood_like_________text________order_by_neighborhood_and_fixtures__explain_select_neighborh" src="https://user-images.githubusercontent.com/9599/129377790-52af28ab-5110-470f-bb1b-a400455e6717.png"> | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898519924 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898519924 | IC_kwDOBm6k_c41jlN0 | 9599 | 2021-08-13T15:03:36Z | 2021-08-13T15:03:36Z | OWNER | Weird edge-case: adding an `order by` changes the order of the columns with respect to the information I am deriving about them. Without order by this gets it right: <img width="702" alt="fixtures__select_neighborhood__facet_cities_name__state_from_facetable_join_facet_cities_on_facetable_city_id___facet_cities_id_where_neighborhood_like_________text________" src="https://user-images.githubusercontent.com/9599/129377247-ec1f67fd-5fc5-46a2-92ef-629276446621.png"> With order by: <img width="708" alt="fixtures__select_neighborhood__facet_cities_name__state_from_facetable_join_facet_cities_on_facetable_city_id___facet_cities_id_where_neighborhood_like_________text________order_by_neighborhood" src="https://user-images.githubusercontent.com/9599/129377339-5b338432-6db8-43ac-9408-48a87c03e5e9.png"> | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898517872 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898517872 | IC_kwDOBm6k_c41jktw | 9599 | 2021-08-13T15:00:50Z | 2021-08-13T15:00:50Z | OWNER | The primary key column (or `rowid`) often resolves to an `index` record in the `sqlite_master` table, e.g. the second row in this: type | name | tbl_name | rootpage | sql -- | -- | -- | -- | -- table | simple_primary_key | simple_primary_key | 2 | CREATE TABLE simple_primary_key ( id varchar(30) primary key, content text ) index | sqlite_autoindex_simple_primary_key_1 | simple_primary_key | 3 | | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898506647 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898506647 | IC_kwDOBm6k_c41jh-X | 9599 | 2021-08-13T14:43:19Z | 2021-08-13T14:43:19Z | OWNER | Work will continue in PR #1434. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/pull/1433#issuecomment-898450402 | https://api.github.com/repos/simonw/datasette/issues/1433 | 898450402 | IC_kwDOBm6k_c41jUPi | 22429695 | 2021-08-13T13:15:55Z | 2021-08-13T13:15:55Z | NONE | # [Codecov](https://codecov.io/gh/simonw/datasette/pull/1433?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report > Merging [#1433](https://codecov.io/gh/simonw/datasette/pull/1433?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (ddba6cc) into [main](https://codecov.io/gh/simonw/datasette/commit/2883098770fc66e50183b2b231edbde20848d4d6?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (2883098) will **not change** coverage. > The diff coverage is `n/a`. [![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/1433/graphs/tree.svg?width=650&height=150&src=pr&token=eSahVY7kw1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)](https://codecov.io/gh/simonw/datasette/pull/1433?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) ```diff @@ Coverage Diff @@ ## main #1433 +/- ## ======================================= Coverage 91.82% 91.82% ======================================= Files 34 34 Lines 4418 4418 ======================================= Hits 4057 4057 Misses 361 361 ``` ------ [Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/1433?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). > **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) > `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data` > Powered by [Codecov](https://codecov… | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
970386262 | |
https://github.com/simonw/datasette/issues/1429#issuecomment-898185944 | https://api.github.com/repos/simonw/datasette/issues/1429 | 898185944 | IC_kwDOBm6k_c41iTrY | 9599 | 2021-08-13T04:37:41Z | 2021-08-13T04:37:41Z | OWNER | If a count is available and the count is less than 1,000 it could say "Show all" instead. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
969548935 | |
https://github.com/simonw/datasette/issues/1432#issuecomment-898084675 | https://api.github.com/repos/simonw/datasette/issues/1432 | 898084675 | IC_kwDOBm6k_c41h69D | 9599 | 2021-08-13T01:11:30Z | 2021-08-13T01:11:30Z | OWNER | It's only `datasette-publish-vercel` that will break the actual functionality - the others will have broken tests. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
969855774 | |
https://github.com/simonw/datasette/issues/1432#issuecomment-898079507 | https://api.github.com/repos/simonw/datasette/issues/1432 | 898079507 | IC_kwDOBm6k_c41h5sT | 9599 | 2021-08-13T01:08:42Z | 2021-08-13T01:09:41Z | OWNER | This is going to break some plugins: https://ripgrep.datasette.io/-/ripgrep?pattern=config%3D&literal=on&glob=%21datasette%2F** > ### datasette-cluster-map/tests/test_cluster_map.py > > @pytest.mark.asyncio > > async def test_respects_base_url(): > ds = Datasette([], memory=True, config={"base_url": "/foo/"}) > response = await ds.client.get("/:memory:?sql=select+1+as+latitude,+2+as+longitude") > assert ( > > ### datasette-export-notebook/tests/test_export_notebook.py > > @pytest.mark.asyncio > > async def test_notebook_no_csv(db_path): > datasette = Datasette([db_path], config={"allow_csv_stream": False}) > response = await datasette.client.get("/db/big.Notebook") > assert ".csv" not in response.text > > ### datasette-publish-vercel/tests/test_publish_vercel.py > metadata=metadata, > cors=True, > config={"default_page_size": 10, "sql_time_limit_ms": 2000} > ).app() > """ > > ### datasette-publish-vercel/datasette_publish_vercel/__init__.py > metadata=metadata{extras}, > cors=True, > config={settings} > > ).app() > > """.strip() > > ### datasette-search-all/tests/test_search_all.py > > async def test_base_url(db_path, path): > sqlite_utils.Database(db_path)["creatures"].enable_fts(["name", "description"]) > datasette = Datasette([db_path], config={"base_url": "/foo/"}) > response = await datasette.client.get(path) > assert response.status_code == 200 I should fix those as soon as this goes out in a release. I won't close this issue until then. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
969855774 | |
https://github.com/simonw/datasette/issues/1432#issuecomment-898074849 | https://api.github.com/repos/simonw/datasette/issues/1432 | 898074849 | IC_kwDOBm6k_c41h4jh | 9599 | 2021-08-13T01:03:40Z | 2021-08-13T01:03:40Z | OWNER | Also this method: https://github.com/simonw/datasette/blob/77f46297a88ac7e49dad2139410b01ee56d5f99c/datasette/app.py#L422-L424 And the places that use it: https://github.com/simonw/datasette/blob/fc4846850fffd54561bc125332dfe97bb41ff42e/datasette/views/base.py#L617 https://github.com/simonw/datasette/blob/fc4846850fffd54561bc125332dfe97bb41ff42e/datasette/views/database.py#L459 Which is used in this template: https://github.com/simonw/datasette/blob/77f46297a88ac7e49dad2139410b01ee56d5f99c/datasette/templates/table.html#L204 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
969855774 | |
https://github.com/simonw/datasette/issues/1431#issuecomment-898072940 | https://api.github.com/repos/simonw/datasette/issues/1431 | 898072940 | IC_kwDOBm6k_c41h4Fs | 9599 | 2021-08-13T00:58:40Z | 2021-08-13T00:58:40Z | OWNER | While I'm doing this I should rename this internal variable to avoid confusion in the future: https://github.com/simonw/datasette/blob/e837095ef35ae155b4c78cc9a8b7133a48c94f03/datasette/app.py#L203 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
969840302 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-813134386 | https://api.github.com/repos/simonw/datasette/issues/1293 | 813134386 | MDEyOklzc3VlQ29tbWVudDgxMzEzNDM4Ng== | 9599 | 2021-04-05T01:20:28Z | 2021-08-13T00:42:30Z | OWNER | ... that output might also provide a better way to extract variables than the current mechanism using a regular expression, by looking for the `Variable` opcodes. [UPDATE: it did indeed do that, see #1421] | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898066466 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898066466 | IC_kwDOBm6k_c41h2gi | 9599 | 2021-08-13T00:40:24Z | 2021-08-13T00:40:24Z | OWNER | It figures out renamed columns too: <img width="694" alt="fixtures__select_created__state_as_the_state_from_facetable" src="https://user-images.githubusercontent.com/9599/129287208-1347fe80-f62e-4ed2-80c6-06a223cbe749.png"> | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898065948 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898065948 | IC_kwDOBm6k_c41h2Yc | 9599 | 2021-08-13T00:38:58Z | 2021-08-13T00:38:58Z | OWNER | Trying to run `explain select * from facetable` fails with an error in my prototype, because it tries to execute `explain explain select * from facetable` - so I need to spot that error and ignore it. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898065011 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898065011 | IC_kwDOBm6k_c41h2Jz | 9599 | 2021-08-13T00:36:30Z | 2021-08-13T00:36:30Z | OWNER | > https://latest.datasette.io/fixtures?sql=explain+select+*+from+paginated_view will be an interesting test query - because `paginated_view` is defined like this: > > ```sql > CREATE VIEW paginated_view AS > SELECT > content, > '- ' || content || ' -' AS content_extra > FROM no_primary_key; > ``` > > So this will help test that the mechanism isn't confused by output columns that are created through a concatenation expression. Here's what it does for that: <img width="748" alt="fixtures__select___from_paginated_view" src="https://user-images.githubusercontent.com/9599/129286962-426bfa56-3946-447a-996d-668b4d80f5c1.png"> | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898063815 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898063815 | IC_kwDOBm6k_c41h13H | 9599 | 2021-08-13T00:33:17Z | 2021-08-13T00:33:17Z | OWNER | Improved version of that function: ```python def columns_for_query(conn, sql): """ Given a SQLite connection ``conn`` and a SQL query ``sql``, returns a list of ``(table_name, column_name)`` pairs, one per returned column. ``(None, None)`` if no table and column could be derived. """ rows = conn.execute('explain ' + sql).fetchall() table_rootpage_by_register = {r['p1']: r['p2'] for r in rows if r['opcode'] == 'OpenRead'} names_by_rootpage = dict( conn.execute( 'select rootpage, name from sqlite_master where rootpage in ({})'.format( ', '.join(map(str, table_rootpage_by_register.values())) ) ) ) columns_by_column_register = {} for row in rows: if row['opcode'] in ('Rowid', 'Column'): addr, opcode, table_id, cid, column_register, p4, p5, comment = row table = names_by_rootpage[table_rootpage_by_register[table_id]] columns_by_column_register[column_register] = (table, cid) result_row = [dict(r) for r in rows if r['opcode'] == 'ResultRow'][0] registers = list(range(result_row["p1"], result_row["p1"] + result_row["p2"])) all_column_names = {} for table in names_by_rootpage.values(): table_xinfo = conn.execute('pragma table_xinfo({})'.format(table)).fetchall() for row in table_xinfo: all_column_names[(table, row["cid"])] = row["name"] final_output = [] for r in registers: try: table, cid = columns_by_column_register[r] final_output.append((table, all_column_names[table, cid])) except KeyError: final_output.append((None, None)) return final_output ``` It works! <img width="1440" alt="Banners_and_Alerts_and_fixtures__select_attraction_id__roadside_attractions_name__characteristic_id__attraction_characteristic_name_as_characteristic_from_roadside_attraction_characteristics_join_roadside_attractions_on_roadside_attractions" src="… | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/1293#issuecomment-898056013 | https://api.github.com/repos/simonw/datasette/issues/1293 | 898056013 | IC_kwDOBm6k_c41hz9N | 9599 | 2021-08-13T00:12:09Z | 2021-08-13T00:12:09Z | OWNER | Having added column metadata in #1430 (ref #942) I could also include a definition list at the top of the query results page exposing the column descriptions for any columns, using the same EXPLAIN mechanism. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
849978964 | |
https://github.com/simonw/datasette/issues/942#issuecomment-898051645 | https://api.github.com/repos/simonw/datasette/issues/942 | 898051645 | IC_kwDOBm6k_c41hy49 | 9599 | 2021-08-13T00:02:25Z | 2021-08-13T00:02:25Z | OWNER | And on mobile: ![5FAF8D73-7199-4BB7-A5B8-9E46DCB4A985](https://user-images.githubusercontent.com/9599/129284817-dc13cbf4-144e-4f4c-8fb7-470602e2eea0.jpeg) | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681334912 | |
https://github.com/simonw/datasette/issues/942#issuecomment-898050457 | https://api.github.com/repos/simonw/datasette/issues/942 | 898050457 | IC_kwDOBm6k_c41hymZ | 9599 | 2021-08-12T23:59:53Z | 2021-08-12T23:59:53Z | OWNER | Documentation: https://docs.datasette.io/en/latest/metadata.html#column-descriptions Live demo: https://latest.datasette.io/fixtures/roadside_attractions <img width="1045" alt="fixtures__roadside_attractions__4_rows" src="https://user-images.githubusercontent.com/9599/129284675-ef2fd6ed-54ba-4f6a-add5-7a9253921279.png"> | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681334912 | |
https://github.com/simonw/datasette/pull/1430#issuecomment-898043575 | https://api.github.com/repos/simonw/datasette/issues/1430 | 898043575 | IC_kwDOBm6k_c41hw63 | 22429695 | 2021-08-12T23:39:36Z | 2021-08-12T23:49:51Z | NONE | # [Codecov](https://codecov.io/gh/simonw/datasette/pull/1430?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report > Merging [#1430](https://codecov.io/gh/simonw/datasette/pull/1430?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (9419947) into [main](https://codecov.io/gh/simonw/datasette/commit/b1fed48a95516ae84c0f020582303ab50ab817e2?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (b1fed48) will **increase** coverage by `0.00%`. > The diff coverage is `100.00%`. [![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/1430/graphs/tree.svg?width=650&height=150&src=pr&token=eSahVY7kw1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)](https://codecov.io/gh/simonw/datasette/pull/1430?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) ```diff @@ Coverage Diff @@ ## main #1430 +/- ## ======================================= Coverage 91.71% 91.71% ======================================= Files 34 34 Lines 4417 4418 +1 ======================================= + Hits 4051 4052 +1 Misses 366 366 ``` | [Impacted Files](https://codecov.io/gh/simonw/datasette/pull/1430?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | | |---|---|---| | [datasette/views/table.py](https://codecov.io/gh/simonw/datasette/pull/1430/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3ZpZXdzL3RhYmxlLnB5) | `96.00% <100.00%> (+<0.01%)` | :arrow_up: | ------ [Con… | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
969758038 | |
https://github.com/simonw/datasette/issues/942#issuecomment-898037650 | https://api.github.com/repos/simonw/datasette/issues/942 | 898037650 | IC_kwDOBm6k_c41hveS | 9599 | 2021-08-12T23:23:54Z | 2021-08-12T23:23:54Z | OWNER | I like this enough that I'm going to ship it as an alpha and try it out on a couple of live projects. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681334912 | |
https://github.com/simonw/datasette/issues/942#issuecomment-898037456 | https://api.github.com/repos/simonw/datasette/issues/942 | 898037456 | IC_kwDOBm6k_c41hvbQ | 9599 | 2021-08-12T23:23:34Z | 2021-08-12T23:23:34Z | OWNER | Prototype with a `<dl>`: <img width="721" alt="fixtures__sortable__201_rows" src="https://user-images.githubusercontent.com/9599/129282175-c94dcf74-beb3-4f0a-9106-f75d19369fb0.png"> ```diff diff --git a/datasette/static/app.css b/datasette/static/app.css index c6be1e9..bf068fd 100644 --- a/datasette/static/app.css +++ b/datasette/static/app.css @@ -836,6 +841,16 @@ svg.dropdown-menu-icon { background-repeat: no-repeat; } +dl.column-descriptions dt { + font-weight: bold; +} +dl.column-descriptions dd { + padding-left: 1.5em; + white-space: pre-wrap; + line-height: 1.1em; + color: #666; +} + .anim-scale-in { animation-name: scale-in; animation-duration: 0.15s; diff --git a/datasette/templates/table.html b/datasette/templates/table.html index 211352b..466e8a4 100644 --- a/datasette/templates/table.html +++ b/datasette/templates/table.html @@ -51,6 +51,14 @@ {% block description_source_license %}{% include "_description_source_license.html" %}{% endblock %} +{% if metadata.columns %} +<dl class="column-descriptions"> + {% for column_name, column_description in metadata.columns.items() %} + <dt>{{ column_name }}</dt><dd>{{ column_description }}</dd> + {% endfor %} +</dl> +{% endif %} + {% if filtered_table_rows_count or human_description_en %} <h3>{% if filtered_table_rows_count or filtered_table_rows_count == 0 %}{{ "{:,}".format(filtered_table_rows_count) }} row{% if filtered_table_rows_count == 1 %}{% else %}s{% endif %}{% endif %} {% if human_description_en %}{{ human_description_en }}{% endif %} ``` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681334912 | |
https://github.com/simonw/datasette/issues/942#issuecomment-898032118 | https://api.github.com/repos/simonw/datasette/issues/942 | 898032118 | IC_kwDOBm6k_c41huH2 | 596279 | 2021-08-12T23:12:00Z | 2021-08-12T23:12:00Z | NONE | This looks awesome. We'll definitely make extensive use of this feature! On Thu, Aug 12, 2021 at 5:52 PM Simon Willison ***@***.***> wrote: > I like this. Need to solve for mobile though where the cog menu isn't > visible - I think I'll do that with a definition list at the top of the > page. > > — > You are receiving this because you are subscribed to this thread. > Reply to this email directly, view it on GitHub > <https://github.com/simonw/datasette/issues/942#issuecomment-898022235>, > or unsubscribe > <https://github.com/notifications/unsubscribe-auth/AAERSNYEF6QRZO2HRJGRIWDT4RGDFANCNFSM4QEC6ATA> > . > Triage notifications on the go with GitHub Mobile for iOS > <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675> > or Android > <https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email> > . > -- Zane A. Selvans, PhD Chief Data Wrangler Catalyst Cooperative https://catalyst.coop ***@***.*** Signal/WhatsApp/SMS: +1 720 443 1363 Twitter: @ZaneSelvans <https://twitter.com/ZaneSelvans> PGP <https://www.gnupg.org/>: 0x64F7B56F3A127B04 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681334912 | |
https://github.com/simonw/datasette/issues/942#issuecomment-898022235 | https://api.github.com/repos/simonw/datasette/issues/942 | 898022235 | IC_kwDOBm6k_c41hrtb | 9599 | 2021-08-12T22:52:23Z | 2021-08-12T22:52:23Z | OWNER | I like this. Need to solve for mobile though where the cog menu isn't visible - I think I'll do that with a definition list at the top of the page. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681334912 | |
https://github.com/simonw/datasette/issues/942#issuecomment-898021895 | https://api.github.com/repos/simonw/datasette/issues/942 | 898021895 | IC_kwDOBm6k_c41hroH | 9599 | 2021-08-12T22:51:36Z | 2021-08-12T22:51:36Z | OWNER | Prototype: <img width="650" alt="fixtures__sortable__201_rows" src="https://user-images.githubusercontent.com/9599/129279808-08d56b2f-a4d6-4147-b3a6-542c62b566c1.png"> ```diff diff --git a/datasette/static/app.css b/datasette/static/app.css index c6be1e9..5ca64cb 100644 --- a/datasette/static/app.css +++ b/datasette/static/app.css @@ -784,9 +784,14 @@ svg.dropdown-menu-icon { font-size: 0.7em; color: #666; margin: 0; - padding: 0; padding: 4px 8px 4px 8px; } +.dropdown-menu .dropdown-column-description { + margin: 0; + color: #666; + padding: 4px 8px 4px 8px; + max-width: 20em; +} .dropdown-menu li { border-bottom: 1px solid #ccc; } diff --git a/datasette/static/table.js b/datasette/static/table.js index 991346d..a903112 100644 --- a/datasette/static/table.js +++ b/datasette/static/table.js @@ -9,6 +9,7 @@ var DROPDOWN_HTML = `<div class="dropdown-menu"> <li><a class="dropdown-not-blank" href="#">Show not-blank rows</a></li> </ul> <p class="dropdown-column-type"></p> +<p class="dropdown-column-description"></p> </div>`; var DROPDOWN_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> @@ -166,6 +167,14 @@ var DROPDOWN_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="14" heig } else { columnTypeP.style.display = "none"; } + + var columnDescriptionP = menu.querySelector(".dropdown-column-description"); + if (th.dataset.columnDescription) { + columnDescriptionP.innerText = th.dataset.columnDescription; + columnDescriptionP.style.display = 'block'; + } else { + columnDescriptionP.style.display = 'none'; + } menu.style.position = "absolute"; menu.style.top = menuTop + 6 + "px"; menu.style.left = menuLeft + "px"; diff --git a/datasette/templates/_table.html b/datasette/templates/_table.html index d765937..64… | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681334912 | |
https://github.com/simonw/datasette/issues/942#issuecomment-897996296 | https://api.github.com/repos/simonw/datasette/issues/942 | 897996296 | IC_kwDOBm6k_c41hlYI | 9599 | 2021-08-12T22:01:36Z | 2021-08-12T22:01:36Z | OWNER | I'm going with `"columns": {"name-of-column": "description-of-column"}`. If I decide to make `"col"` and `"nocol"` available in metadata I'll use those as the keys in the metadata, for consistency with the existing query string parameters. I'm OK with having both `"columns": ...` and `"col": ...` keys in the metadata, even though they could be a tiny bit confusing without the documentation. | { "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681334912 | |
https://github.com/simonw/datasette/issues/1429#issuecomment-897960049 | https://api.github.com/repos/simonw/datasette/issues/1429 | 897960049 | IC_kwDOBm6k_c41hchx | 9599 | 2021-08-12T20:53:04Z | 2021-08-12T20:53:04Z | OWNER | Maybe something like this: > [Next page](#) - 100 per page ([show 1,000 per page](#)) | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
969548935 | |
https://github.com/simonw/sqlite-utils/issues/186#issuecomment-897600677 | https://api.github.com/repos/simonw/sqlite-utils/issues/186 | 897600677 | IC_kwDOCGYnMM41gEyl | 9308268 | 2021-08-12T12:32:14Z | 2021-08-12T12:32:14Z | NONE | Actually, I forgot to include the `bib_pub_year` in the extract ... But also, I tried again with empty string values instead of `NULL` values and it seems to place the foreign key properly / correctly... ```python3 sql = """\ INSERT INTO "circulation_info" ("item_id", "bib_title", "bib_creator", "bib_format", "bib_pub_year", "checkout_date") VALUES (1, "title one", "creator one", "Book", 2018, "2021-08-12 00:01"), (2, "title two", "creator one", "Book", 2019, "2021-08-12 00:02"), (3, "title three", "", "DVD", 2020, "2021-08-12 00:03"), (4, "title four", "", "DVD", "", "2021-08-12 00:04"), (5, "title five", "", "DVD", "", "2021-08-12 00:05") """ with sqlite3.connect('test_bib_2.db') as con: con.execute(sql) ``` ```python3 db["circulation_info"].extract( [ "bib_title", "bib_creator", "bib_format", "bib_pub_year" ], table="bib_info", fk_column="bib_info_id" ) ``` ``` {'id': 1, 'item_id': 1, 'bib_info_id': 1, 'bib_pub_year': 2018, 'checkout_date': '2021-08-12 00:01'} {'id': 2, 'item_id': 2, 'bib_info_id': 2, 'bib_pub_year': 2019, 'checkout_date': '2021-08-12 00:02'} {'id': 3, 'item_id': 3, 'bib_info_id': 3, 'bib_pub_year': 2020, 'checkout_date': '2021-08-12 00:03'} {'id': 4, 'item_id': 4, 'bib_info_id': 4, 'bib_pub_year': '', 'checkout_date': '2021-08-12 00:04'} {'id': 5, 'item_id': 5, 'bib_info_id': 5, 'bib_pub_year': '', 'checkout_date': '2021-08-12 00:05'} --- {'id': 1, 'bib_title': 'title one', 'bib_creator': 'creator one', 'bib_format': 'Book'} {'id': 2, 'bib_title': 'title two', 'bib_creator': 'creator one', 'bib_format': 'Book'} {'id': 3, 'bib_title': 'title three', 'bib_creator': '', 'bib_format': 'DVD'} {'id': 4, 'bib_title': 'title four', 'bib_creator': '', 'bib_format': 'DVD'} {'id': 5, 'bib_title': 'title five', 'bib_creator': '', 'bib_format': 'DVD'} ``` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
722816436 | |
https://github.com/simonw/sqlite-utils/issues/186#issuecomment-897588624 | https://api.github.com/repos/simonw/sqlite-utils/issues/186 | 897588624 | IC_kwDOCGYnMM41gB2Q | 9308268 | 2021-08-12T12:13:25Z | 2021-08-12T12:13:25Z | NONE | I think I ran into an issue that's perhaps related with `extract()` I have a case where I want to create a lookup table for all the related title data where there are possibly multiple null values in the related columns .... ```python3 sql = """\ INSERT INTO "circulation_info" ("item_id", "bib_title", "bib_creator", "bib_format", "bib_pub_year", "checkout_date") VALUES (1, "title one", "creator one", "Book", 2018, "2021-08-12 00:01"), (2, "title two", "creator one", "Book", 2019, "2021-08-12 00:02"), (3, "title three", NULL, "DVD", 2020, "2021-08-12 00:03"), (4, "title four", NULL, "DVD", NULL, "2021-08-12 00:04"), (5, "title five", NULL, "DVD", NULL, "2021-08-12 00:05") """ with sqlite3.connect('test_bib.db') as con: con.execute(sql) ``` when I run the `extract()` method ... ```python3 db["circulation_info"].extract( [ "bib_title", "bib_creator", "bib_format" ], table="bib_info", fk_column="bib_info_id" ) db = sqlite_utils.Database("test_bib.db") for row in db["circulation_info"].rows: print(row) print("\n---\n") for row in db["bib_info"].rows: print(row) ``` results in this .. ``` {'id': 1, 'item_id': 1, 'bib_info_id': 1, 'bib_pub_year': 2018, 'checkout_date': '2021-08-12 00:01'} {'id': 2, 'item_id': 2, 'bib_info_id': 2, 'bib_pub_year': 2019, 'checkout_date': '2021-08-12 00:02'} {'id': 3, 'item_id': 3, 'bib_info_id': None, 'bib_pub_year': 2020, 'checkout_date': '2021-08-12 00:03'} {'id': 4, 'item_id': 4, 'bib_info_id': None, 'bib_pub_year': None, 'checkout_date': '2021-08-12 00:04'} {'id': 5, 'item_id': 5, 'bib_info_id': None, 'bib_pub_year': None, 'checkout_date': '2021-08-12 00:05'} --- {'id': 1, 'bib_title': 'title one', 'bib_creator': 'creator one', 'bib_format': 'Book'} {'id': 2, 'bib_title': 'title two', 'bib_creator': 'creator one', 'bib_format': 'Book'} {'id': 3, 'bib_title': 'title three', 'bib_creator': None, 'bib_format': 'DVD'} {'id': 4, 'bib_title': 'title four', 'bib_cre… | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
722816436 | |
https://github.com/simonw/sqlite-utils/issues/311#issuecomment-896381184 | https://api.github.com/repos/simonw/sqlite-utils/issues/311 | 896381184 | IC_kwDOCGYnMM41bbEA | 9599 | 2021-08-10T23:33:33Z | 2021-08-10T23:33:33Z | OWNER | Now live at https://sqlite-utils.datasette.io/en/latest/reference.html TIL from what I learned today here: https://til.simonwillison.net/sphinx/sphinx-autodoc | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
965102534 | |
https://github.com/dogsheep/google-takeout-to-sqlite/pull/8#issuecomment-896378525 | https://api.github.com/repos/dogsheep/google-takeout-to-sqlite/issues/8 | 896378525 | IC_kwDODFE5qs41baad | 28565 | 2021-08-10T23:28:45Z | 2021-08-10T23:28:45Z | NONE | I added parsing of text/html emails using BeautifulSoup. Around half of the emails in my archive don't include a text/plain payload so adding html parsing makes a good chunk of them searchable. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
954546309 | |
https://github.com/simonw/sqlite-utils/pull/312#issuecomment-896162082 | https://api.github.com/repos/simonw/sqlite-utils/issues/312 | 896162082 | IC_kwDOCGYnMM41alki | 22429695 | 2021-08-10T17:10:39Z | 2021-08-10T23:07:35Z | NONE | # [Codecov](https://codecov.io/gh/simonw/sqlite-utils/pull/312?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report > Merging [#312](https://codecov.io/gh/simonw/sqlite-utils/pull/312?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (43bc064) into [main](https://codecov.io/gh/simonw/sqlite-utils/commit/ee469e3122d6f5973ec2584c1580d930daca2e7c?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (ee469e3) will **decrease** coverage by `0.02%`. > The diff coverage is `96.84%`. [![Impacted file tree graph](https://codecov.io/gh/simonw/sqlite-utils/pull/312/graphs/tree.svg?width=650&height=150&src=pr&token=O0X3703L9P&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)](https://codecov.io/gh/simonw/sqlite-utils/pull/312?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) ```diff @@ Coverage Diff @@ ## main #312 +/- ## ========================================== - Coverage 96.30% 96.28% -0.03% ========================================== Files 5 5 Lines 2168 2179 +11 ========================================== + Hits 2088 2098 +10 - Misses 80 81 +1 ``` | [Impacted Files](https://codecov.io/gh/simonw/sqlite-utils/pull/312?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/312/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-c3FsaXRlX3V0aWxzL2RiLnB5) | `97.91% <96.84%> (-0.08%)` … | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
965143346 | |
https://github.com/simonw/sqlite-utils/issues/314#issuecomment-896369551 | https://api.github.com/repos/simonw/sqlite-utils/issues/314 | 896369551 | IC_kwDOCGYnMM41bYOP | 9599 | 2021-08-10T23:06:41Z | 2021-08-10T23:06:41Z | OWNER | I took a big bite out of this when I annotated the ``.insert()`` method - but there are a bunch of other places that still need doing: https://github.com/simonw/sqlite-utils/blob/43bc06481783c3cfcee70c0cb541a686e8894adb/sqlite_utils/db.py#L2382-L2397 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
965210966 | |
https://github.com/simonw/sqlite-utils/issues/314#issuecomment-896344833 | https://api.github.com/repos/simonw/sqlite-utils/issues/314 | 896344833 | IC_kwDOCGYnMM41bSMB | 9599 | 2021-08-10T22:07:34Z | 2021-08-10T22:07:34Z | OWNER | Also the `.insert()` family of methods - they look pretty ugly in Sphinx right now: <img width="688" alt="API_Reference_—_sqlite-utils_3_15-16-gf51b712_documentation" src="https://user-images.githubusercontent.com/9599/128941267-51b290cb-6c3d-44b7-a584-e3ae3a819e8b.png"> I should probably define reusable types for things like `pk=`, which have complex type signatures (a string or a list/tuple of strings) and show up in multiple places. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
965210966 | |
https://github.com/simonw/sqlite-utils/issues/315#issuecomment-896339144 | https://api.github.com/repos/simonw/sqlite-utils/issues/315 | 896339144 | IC_kwDOCGYnMM41bQzI | 9599 | 2021-08-10T21:55:41Z | 2021-08-10T21:55:41Z | OWNER | Or should we raise an error if you attempt to call `.delete_where()` on a table that doesn't exist? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
965440017 | |
https://github.com/simonw/sqlite-utils/pull/312#issuecomment-896284722 | https://api.github.com/repos/simonw/sqlite-utils/issues/312 | 896284722 | IC_kwDOCGYnMM41bDgy | 9599 | 2021-08-10T20:08:03Z | 2021-08-10T20:08:21Z | OWNER | Spotted a rogue backtick: ![A0147E27-7506-49B0-BEFB-20D99BBFEBAD](https://user-images.githubusercontent.com/9599/128927930-b3333dee-a385-409b-a945-f108e6ea40df.jpeg) | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
965143346 | |
https://github.com/simonw/sqlite-utils/pull/312#issuecomment-896200682 | https://api.github.com/repos/simonw/sqlite-utils/issues/312 | 896200682 | IC_kwDOCGYnMM41au_q | 9599 | 2021-08-10T18:03:40Z | 2021-08-10T18:03:40Z | OWNER | Adding type signatures to `create_table()` and `.create_table_sql()` is a bit too involved, I'll do that in a separate issue. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
965143346 | |
https://github.com/simonw/sqlite-utils/pull/312#issuecomment-896186025 | https://api.github.com/repos/simonw/sqlite-utils/issues/312 | 896186025 | IC_kwDOCGYnMM41arap | 9599 | 2021-08-10T17:42:51Z | 2021-08-10T17:42:51Z | OWNER | That worked! https://sqlite-utils.datasette.io/en/autodoc/reference.html | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
965143346 | |
https://github.com/simonw/sqlite-utils/pull/312#issuecomment-896182934 | https://api.github.com/repos/simonw/sqlite-utils/issues/312 | 896182934 | IC_kwDOCGYnMM41aqqW | 9599 | 2021-08-10T17:38:44Z | 2021-08-10T17:38:44Z | OWNER | From https://docs.readthedocs.io/en/stable/config-file/v2.html#packages it looks like I can tell Read The Docs to run `pip install -e .` using a `.readthedocs.yaml` configuration: ```yaml version: 2 sphinx: configuration: docs/conf.py python: version: "3.9" install: - method: pip path: . extra_requirements: - docs ``` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
965143346 | |
https://github.com/simonw/sqlite-utils/pull/312#issuecomment-896180956 | https://api.github.com/repos/simonw/sqlite-utils/issues/312 | 896180956 | IC_kwDOCGYnMM41aqLc | 9599 | 2021-08-10T17:35:51Z | 2021-08-10T17:35:51Z | OWNER | Reading the rest of https://sphinx-rtd-tutorial.readthedocs.io/en/latest/sphinx-config.html#autodoc-configuration it suggests using a `requirements.txt` file to install dependencies - but I use `setup.py` for that so I need to figure out a different pattern here. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
965143346 | |
https://github.com/simonw/sqlite-utils/pull/312#issuecomment-896175438 | https://api.github.com/repos/simonw/sqlite-utils/issues/312 | 896175438 | IC_kwDOCGYnMM41ao1O | 9599 | 2021-08-10T17:28:19Z | 2021-08-10T17:28:19Z | OWNER | https://sphinx-rtd-tutorial.readthedocs.io/en/latest/sphinx-config.html#autodoc-configuration says do something like this at the top of `conf.py`: ```python import os import sys sys.path.insert(0, os.path.abspath('../../simpleble/')) ``` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
965143346 | |
https://github.com/simonw/sqlite-utils/pull/312#issuecomment-896174456 | https://api.github.com/repos/simonw/sqlite-utils/issues/312 | 896174456 | IC_kwDOCGYnMM41aol4 | 9599 | 2021-08-10T17:27:01Z | 2021-08-10T17:27:01Z | OWNER | Docs are now building at https://sqlite-utils.datasette.io/en/autodoc/reference.html But there's a problem! The page is semi-blank: <img width="663" alt="Reference_—_sqlite-utils_3_15-6-gc11ff89_documentation" src="https://user-images.githubusercontent.com/9599/128906373-7463e0c9-3b08-4b15-a73a-84b8ba6ab342.png"> I need to teach Read The Docs how to ensure `sqlite_utils` is available for introspection. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
965143346 | |
https://github.com/simonw/sqlite-utils/pull/312#issuecomment-896156971 | https://api.github.com/repos/simonw/sqlite-utils/issues/312 | 896156971 | IC_kwDOCGYnMM41akUr | 9599 | 2021-08-10T17:04:22Z | 2021-08-10T17:05:59Z | OWNER | I'm going to get Read The Docs to build the docs for this branch too - on https://readthedocs.org/projects/sqlite-utils/versions/ I am clicking this button: <img width="881" alt="Versions___Read_the_Docs" src="https://user-images.githubusercontent.com/9599/128903015-0f2649e7-34a8-4dfd-984c-b1b5bd8a98be.png"> I then set it to "active" (so pushes to the branch will build it) and "hidden" (so it wouldn't show up in search or in the navigation menu). https://docs.readthedocs.io/en/stable/versions.html#version-states <img width="846" alt="autodoc_-_sqlite-utils___Read_the_Docs" src="https://user-images.githubusercontent.com/9599/128903217-efe827c6-4f54-42dd-943e-ddf9ab3a05d8.png"> | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
965143346 |