{"id": 1160407071, "node_id": "I_kwDOBm6k_c5FKmgf", "number": 1647, "title": "Test failures with SQLite 3.37.0+ due to column affinity case", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 5, "created_at": "2022-03-05T17:37:46Z", "updated_at": "2022-03-05T19:56:28Z", "closed_at": "2022-03-05T19:47:04Z", "author_association": "OWNER", "pull_request": null, "body": "These three tests are failing on my local machine:\r\n```\r\nFAILED tests/test_internals_database.py::test_table_column_details[facetable-expected0] - AssertionError: assert [Column(cid=0, name='pk', type='INTEGER', no...\r\nFAILED tests/test_internals_database.py::test_table_column_details[sortable-expected1] - AssertionError: assert [Column(cid=0, name='pk1', type='varchar(30)'...\r\nFAILED tests/test_table_html.py::test_sort_links - AssertionError: assert [{'a_href': None,\\n 'attrs': {'class': ['col-Link'],\\n 'data-column': '...\r\n```\r\nI ran `pytest --lf -vv` and the output had things like this in it:\r\n```\r\nE - Column(cid=1, name='created', type='text', notnull=0, default_value=None, is_pk=0, hidden=0),\r\nE ? ^^^^\r\nE + Column(cid=1, name='created', type='TEXT', notnull=0, default_value=None, is_pk=0, hidden=0),\r\n...\r\nE {'a_href': '/fixtures/sortable?_sort=sortable_with_nulls_2',\r\nE 'attrs': {'class': ['col-sortable_with_nulls_2'],\r\nE 'data-column': 'sortable_with_nulls_2',\r\nE 'data-column-not-null': '0',\r\nE - 'data-column-type': 'real',\r\nE ? ^^^^\r\nE + 'data-column-type': 'REAL',\r\nE ? ^^^^\r\n```\r\nSomething is causing column types to come back in uppercase where previously they were lowercase.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1647/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1160327106, "node_id": "PR_kwDODEm0Qs4z_V3w", "number": 65, "title": "Update Twitter dev link, clarify apps vs projects", "user": {"value": 2657547, "label": "rixx"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2022-03-05T11:56:08Z", "updated_at": "2022-03-05T11:56:08Z", "closed_at": null, "author_association": "FIRST_TIME_CONTRIBUTOR", "pull_request": "dogsheep/twitter-to-sqlite/pulls/65", "body": "Twitter pushes you heavily towards v2 projects instead of v1 apps \u2013 I know the README mentions v1 API compatibility at the top, but I still nearly got turned around here.", "repo": {"value": 206156866, "label": "twitter-to-sqlite"}, "type": "pull", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/dogsheep/twitter-to-sqlite/issues/65/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": 0, "state_reason": null} {"id": 1148725876, "node_id": "I_kwDOBm6k_c5EeCp0", "number": 1640, "title": "Support static assets where file length may change, e.g. logs", "user": {"value": 57859326, "label": "broccolihighkicks"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2022-02-24T00:34:42Z", "updated_at": "2022-03-05T01:19:25Z", "closed_at": null, "author_association": "NONE", "pull_request": null, "body": "This is a bit of an oxymoron.\r\n\r\nI am serving a log.txt file for a background process using the Datasette --static CLI. This is useful as I can observe a background process from the web UI to see any errors that occur (instead of spelunking the logs via docker exec/ssh etc).\r\n\r\nI get this error, which I think is because Datasette assumes that the size of the content does not change (but appending new log lines means the content length changes).\r\n\r\n\r\n```python\r\nTraceback (most recent call last):\r\n File \"/usr/local/lib/python3.9/site-packages/datasette/app.py\", line 1181, in route_path\r\n response = await view(request, send)\r\n File \"/usr/local/lib/python3.9/site-packages/datasette/utils/asgi.py\", line 305, in inner_static\r\n await asgi_send_file(send, full_path, chunk_size=chunk_size)\r\n File \"/usr/local/lib/python3.9/site-packages/datasette/utils/asgi.py\", line 280, in asgi_send_file\r\n await send(\r\n File \"/usr/local/lib/python3.9/site-packages/asgi_csrf.py\", line 104, in wrapped_send\r\n await send(event)\r\n File \"/usr/local/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py\", line 460, in send\r\n output = self.conn.send(event)\r\n File \"/usr/local/lib/python3.9/site-packages/h11/_connection.py\", line 468, in send\r\n data_list = self.send_with_data_passthrough(event)\r\n File \"/usr/local/lib/python3.9/site-packages/h11/_connection.py\", line 501, in send_with_data_passthrough\r\n writer(event, data_list.append)\r\n File \"/usr/local/lib/python3.9/site-packages/h11/_writers.py\", line 58, in __call__\r\n self.send_data(event.data, write)\r\n File \"/usr/local/lib/python3.9/site-packages/h11/_writers.py\", line 78, in send_data\r\n raise LocalProtocolError(\"Too much data for declared Content-Length\")\r\nh11._util.LocalProtocolError: Too much data for declared Content-Length\r\nERROR: Exception in ASGI application\r\nTraceback (most recent call last):\r\n File \"/usr/local/lib/python3.9/site-packages/datasette/app.py\", line 1181, in route_path\r\n response = await view(request, send)\r\n File \"/usr/local/lib/python3.9/site-packages/datasette/utils/asgi.py\", line 305, in inner_static\r\n await asgi_send_file(send, full_path, chunk_size=chunk_size)\r\n File \"/usr/local/lib/python3.9/site-packages/datasette/utils/asgi.py\", line 280, in asgi_send_file\r\n await send(\r\n File \"/usr/local/lib/python3.9/site-packages/asgi_csrf.py\", line 104, in wrapped_send\r\n await send(event)\r\n File \"/usr/local/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py\", line 460, in send\r\n output = self.conn.send(event)\r\n File \"/usr/local/lib/python3.9/site-packages/h11/_connection.py\", line 468, in send\r\n data_list = self.send_with_data_passthrough(event)\r\n File \"/usr/local/lib/python3.9/site-packages/h11/_connection.py\", line 501, in send_with_data_passthrough\r\n writer(event, data_list.append)\r\n File \"/usr/local/lib/python3.9/site-packages/h11/_writers.py\", line 58, in __call__\r\n self.send_data(event.data, write)\r\n File \"/usr/local/lib/python3.9/site-packages/h11/_writers.py\", line 78, in send_data\r\n raise LocalProtocolError(\"Too much data for declared Content-Length\")\r\nh11._util.LocalProtocolError: Too much data for declared Content-Length\r\n```\r\n\r\nThanks, I am finding Datasette very useful.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1640/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1152072027, "node_id": "I_kwDOBm6k_c5Eqzlb", "number": 1642, "title": "Dependency issue with asgiref and uvicorn", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-02-26T18:00:35Z", "updated_at": "2022-03-05T01:11:27Z", "closed_at": "2022-03-05T01:11:17Z", "author_association": "OWNER", "pull_request": null, "body": "```\r\nERROR: After October 2020 you may experience errors when installing or updating packages. This is because pip will change the way that it resolves dependency conflicts.\r\n\r\nWe recommend you use --use-feature=2020-resolver to test your packages with the new resolver before it becomes the default.\r\n\r\ndatasette 0.60.2 requires asgiref<3.5.0,>=3.2.10, but you'll have asgiref 3.5.0 which is incompatible.\r\n```\r\nThat's after I forced an upgrade of `uvicorn` due to this warning:\r\n```\r\nERROR: After October 2020 you may experience errors when installing or updating packages. This is because pip will change the way that it resolves dependency conflicts.\r\n\r\nWe recommend you use --use-feature=2020-resolver to test your packages with the new resolver before it becomes the default.\r\n\r\nuvicorn 0.13.1 requires click==7.*, but you'll have click 8.0.4 which is incompatible.\r\n```", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1642/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1063388037, "node_id": "I_kwDOCGYnMM4_YgOF", "number": 343, "title": "Provide function to generate hash_id from specified columns", "user": {"value": 82988, "label": "psychemedia"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2021-11-25T10:12:12Z", "updated_at": "2022-03-02T04:25:25Z", "closed_at": "2022-03-02T04:25:25Z", "author_association": "NONE", "pull_request": null, "body": "Hi\r\n\r\nI note that you define `_hash()` to create a `hash_id` from non-id column values in a table [here](https://github.com/simonw/sqlite-utils/blob/8f386a0d300d1b1c76132bb75972b755049fb742/sqlite_utils/db.py#L2996).\r\n\r\nIt would be useful to be able to call a complementary function to generate a corresponding `_id` from a subset of specified columns when adding items to another table, eg to support the creation of foreign keys.\r\n\r\nOr is there a better pattern for doing that?", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/343/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1149402080, "node_id": "PR_kwDODFdgUs4zaUta", "number": 70, "title": "scrape-dependents: enable paging through package menu option if present", "user": {"value": 36061055, "label": "stanbiryukov"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2022-02-24T15:07:25Z", "updated_at": "2022-02-24T15:07:25Z", "closed_at": null, "author_association": "FIRST_TIME_CONTRIBUTOR", "pull_request": "dogsheep/github-to-sqlite/pulls/70", "body": "Some repos organize network dependents by a Package toggle. This PR adds the ability to page through those options and scrape underlying dependents.", "repo": {"value": 207052882, "label": "github-to-sqlite"}, "type": "pull", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/dogsheep/github-to-sqlite/issues/70/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": 0, "state_reason": null} {"id": 1149310456, "node_id": "I_kwDOBm6k_c5EgRX4", "number": 1641, "title": "Tweak mobile keyboard settings", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-02-24T13:47:10Z", "updated_at": "2022-02-24T13:49:26Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "https://developer.apple.com/library/archive/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html#//apple_ref/doc/uid/TP40009542-CH5-SW12\r\n\r\n`autocorrect=\"off\"` is worth experimenting with.\r\n\r\nTwitter: https://twitter.com/forestgregg/status/1496842959563726852", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1641/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1148638868, "node_id": "I_kwDOBm6k_c5EdtaU", "number": 1639, "title": "Make datasette-redirect-forbidden unneccessary", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2022-02-23T22:18:46Z", "updated_at": "2022-02-23T22:18:46Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "I wrote `datasette-redirect-forbidden` today because I needed 403 errors to redirect to `/-/login` and it was the quickest way to solve that problem.\r\n\r\nThis should be a feature of Datasette core.\r\n\r\n- https://github.com/simonw/datasette-redirect-forbidden/issues/2", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1639/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 677272618, "node_id": "MDU6SXNzdWU2NzcyNzI2MTg=", "number": 928, "title": "Test failures caused by failed attempts to mock pip", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2020-08-11T23:53:18Z", "updated_at": "2022-02-23T16:19:47Z", "closed_at": "2020-08-12T00:07:49Z", "author_association": "OWNER", "pull_request": null, "body": "Errors like this one:\r\n\r\nhttps://github.com/simonw/datasette/pull/927/checks?check_run_id=973559696\r\n\r\n```\r\n2020-08-11T23:36:39.8801334Z =================================== FAILURES ===================================\r\n2020-08-11T23:36:39.8802411Z _________________________________ test_install _________________________________\r\n2020-08-11T23:36:39.8803242Z \r\n2020-08-11T23:36:39.8804935Z thing = \r\n2020-08-11T23:36:39.8806663Z comp = 'main', import_path = 'pip._internal.cli.main'\r\n2020-08-11T23:36:39.8807696Z \r\n2020-08-11T23:36:39.8808728Z def _dot_lookup(thing, comp, import_path):\r\n2020-08-11T23:36:39.8810573Z try:\r\n2020-08-11T23:36:39.8812262Z > return getattr(thing, comp)\r\n2020-08-11T23:36:39.8817136Z E AttributeError: module 'pip._internal.cli' has no attribute 'main'\r\n2020-08-11T23:36:39.8843043Z \r\n2020-08-11T23:36:39.8855951Z /opt/hostedtoolcache/Python/3.8.5/x64/lib/python3.8/unittest/mock.py:1215: AttributeError\r\n2020-08-11T23:36:39.8873372Z \r\n2020-08-11T23:36:39.8877803Z During handling of the above exception, another exception occurred:\r\n2020-08-11T23:36:39.8906532Z \r\n2020-08-11T23:36:39.8925767Z def get_src_prefix():\r\n2020-08-11T23:36:39.8928277Z # type: () -> str\r\n2020-08-11T23:36:39.8930068Z if running_under_virtualenv():\r\n2020-08-11T23:36:39.8949721Z src_prefix = os.path.join(sys.prefix, 'src')\r\n2020-08-11T23:36:39.8951813Z else:\r\n2020-08-11T23:36:39.8969014Z # FIXME: keep src in cwd for now (it is not a temporary folder)\r\n2020-08-11T23:36:39.9012110Z try:\r\n2020-08-11T23:36:39.9013489Z > src_prefix = os.path.join(os.getcwd(), 'src')\r\n2020-08-11T23:36:39.9014538Z E FileNotFoundError: [Errno 2] No such file or directory\r\n2020-08-11T23:36:39.9016122Z \r\n2020-08-11T23:36:39.9017617Z /opt/hostedtoolcache/Python/3.8.5/x64/lib/python3.8/site-packages/pip/_internal/locations.py:50: FileNotFoundError\r\n2020-08-11T23:36:39.9018802Z \r\n2020-08-11T23:36:39.9020070Z During handling of the above exception, another exception occurred:\r\n2020-08-11T23:36:39.9020930Z \r\n2020-08-11T23:36:39.9022275Z args = (), keywargs = {}\r\n2020-08-11T23:36:39.9023183Z \r\n2020-08-11T23:36:39.9024077Z @wraps(func)\r\n2020-08-11T23:36:39.9024984Z def patched(*args, **keywargs):\r\n2020-08-11T23:36:39.9028770Z > with self.decoration_helper(patched,\r\n2020-08-11T23:36:39.9031861Z args,\r\n2020-08-11T23:36:39.9038358Z keywargs) as (newargs, newkeywargs):\r\n2020-08-11T23:36:39.9039654Z \r\n2020-08-11T23:36:39.9040566Z /opt/hostedtoolcache/Python/3.8.5/x64/lib/python3.8/unittest/mock.py:1322: \r\n2020-08-11T23:36:39.9041492Z _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \r\n```", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/928/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1142107925, "node_id": "I_kwDOBm6k_c5EEy8V", "number": 1638, "title": "`filters_from_request` plugin hook docs should mention that returning an async function is allowed", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2022-02-18T00:08:26Z", "updated_at": "2022-02-18T00:08:26Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "https://docs.datasette.io/en/stable/plugin_hooks.html#filters-from-request-request-database-table-datasette doesn't mention that you can return an `async` function - but you can, and in fact Datasette itself uses that here: https://github.com/simonw/datasette/blob/aa7f0037a46eb76ae6fe9bf2a1f616c58738ecdf/datasette/filters.py#L43-L47", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1638/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 335200136, "node_id": "MDU6SXNzdWUzMzUyMDAxMzY=", "number": 327, "title": "Explore if SquashFS can be used to shrink size of packaged Docker containers", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2018-06-24T18:15:16Z", "updated_at": "2022-02-17T23:37:24Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "Inspired by this article: https://cldellow.com/2018/06/22/sqlite-parquet-vtable.html#sqlite-database-indexed--squashed\r\n\r\nhttps://en.wikipedia.org/wiki/SquashFS is \"a compressed read-only file system for Linux\" - which means it could be a really nice fit for Datasette and its read-only SQLite databases.\r\n\r\nIt would be interesting to explore a Dockerfile recipe that used SquashFS to compress the SQLite database file that was bundled up by `datasette package` and friends.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/327/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1125297737, "node_id": "I_kwDOCGYnMM5DEq5J", "number": 402, "title": "Advanced class-based `conversions=` mechanism", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 14, "created_at": "2022-02-06T19:47:41Z", "updated_at": "2022-02-16T10:18:55Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "The `conversions=` parameter works like this at the moment: https://sqlite-utils.datasette.io/en/3.23/python-api.html#converting-column-values-using-sql-functions\r\n\r\n```python\r\ndb[\"places\"].insert(\r\n {\"name\": \"Wales\", \"geometry\": wkt},\r\n conversions={\"geometry\": \"GeomFromText(?, 4326)\"},\r\n)\r\n```\r\nThis proposal is to support values in that dictionary that are objects, not strings, which can represent more complex conversions - spun out from #399.\r\n\r\nNew proposed mechanism:\r\n```python\r\nfrom sqlite_utils.utils import LongitudeLatitude\r\n\r\ndb[\"places\"].insert(\r\n {\r\n \"name\": \"London\",\r\n \"point\": (-0.118092, 51.509865)\r\n },\r\n conversions={\"point\": LongitudeLatitude},\r\n)\r\n```\r\nHere `LongitudeLatitude` is a magical value which does TWO things: it sets up the `GeomFromText(?, 4326)` SQL function, and it handles converting the `(51.509865, -0.118092)` tuple into a `POINT({} {})` string.\r\n\r\nThis would involve a change to the `conversions=` contract - where it usually expects a SQL string fragment, but it can also take an object which combines that SQL string fragment with a Python conversion function.\r\n\r\nBest of all... this resolves the `lat, lon` v.s. `lon, lat` dilemma because you can use `from sqlite_utils.utils import LongitudeLatitude` OR `from sqlite_utils.utils import LatitudeLongitude` depending on which you prefer!\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/sqlite-utils/issues/399#issuecomment-1030739566_", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/402/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 842765105, "node_id": "MDExOlB1bGxSZXF1ZXN0NjAyMjYxMDky", "number": 6, "title": "Add testres-db tool", "user": {"value": 1151557, "label": "ligurio"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2021-03-28T15:43:23Z", "updated_at": "2022-02-16T05:12:05Z", "closed_at": "2022-02-16T05:12:05Z", "author_association": "NONE", "pull_request": "dogsheep/dogsheep.github.io/pulls/6", "body": "", "repo": {"value": 214746582, "label": "dogsheep.github.io"}, "type": "pull", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/dogsheep/dogsheep.github.io/issues/6/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": 0, "state_reason": null} {"id": 1138948786, "node_id": "PR_kwDOCGYnMM4y3yW0", "number": 407, "title": "Add SpatiaLite helpers to CLI", "user": {"value": 25778, "label": "eyeseast"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 7, "created_at": "2022-02-15T16:50:17Z", "updated_at": "2022-02-16T01:49:40Z", "closed_at": "2022-02-16T00:58:08Z", "author_association": "CONTRIBUTOR", "pull_request": "simonw/sqlite-utils/pulls/407", "body": "Closes #398 \r\n\r\nThis adds SpatiaLite helpers to the CLI. \r\n\r\n```sh\r\n# init spatialite when creating a database\r\nsqlite-utils create database.db --enable-wal --init-spatialite\r\n\r\n# add geometry columns\r\n# needs a database, table, geometry column name, type, with optional SRID and not-null\r\n# this will throw an error if the table doesn't already exist\r\nsqlite-utils add-geometry-column database.db table-name geometry --srid 4326 --not-null\r\n\r\n# spatial index an existing table/column\r\n# this will throw an error it the table and column don't exist\r\nsqlite-utils create-spatial-index database.db table-name geometry\r\n```\r\n\r\nDocs and tests are included. ", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "pull", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/407/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": 0, "state_reason": null} {"id": 1128139375, "node_id": "I_kwDOCGYnMM5DPgpv", "number": 405, "title": "`Database(memory_name=\"name\")` constructor argument", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2022-02-09T07:15:03Z", "updated_at": "2022-02-16T01:23:16Z", "closed_at": "2022-02-16T01:23:16Z", "author_association": "OWNER", "pull_request": null, "body": "SQLite in-memory databases can be named, in which case multiple connections can be opened to a shared in-memory database running within the same process.\r\n\r\nDatasette supports this - SQLite could support it too.\r\n\r\nhttps://docs.datasette.io/en/0.60.2/internals.html#database-ds-path-none-is-mutable-false-is-memory-false-memory-name-none", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/405/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1124237013, "node_id": "I_kwDOCGYnMM5DAn7V", "number": 398, "title": "Add SpatiaLite helpers to CLI", "user": {"value": 25778, "label": "eyeseast"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 9, "created_at": "2022-02-04T14:01:28Z", "updated_at": "2022-02-16T01:02:29Z", "closed_at": "2022-02-16T00:58:07Z", "author_association": "CONTRIBUTOR", "pull_request": null, "body": "Now that #385 is merged, add CLI versions of those methods.\r\n\r\n```sh\r\n# init spatialite\r\nsqlite-utils init-spatialite database.db\r\n\r\n# or maybe/also\r\nsqlite-utils create database.db --enable-wal --spatialite\r\n\r\n# add geometry columns\r\n# needs a database, table, geometry column name, type, with optional SRID and not-null\r\n# this needs to create a table if it doesn't already exist\r\nsqlite-utils add-geometry-column database.db table-name geometry --srid 4326 --not-null\r\n\r\n# spatial index an existing table/column\r\nsqlite-utils create-spatial-index database.db table-name geometry\r\n```\r\n\r\nShould be mostly straightforward. The one thing worth highlighting in docs is that geometry columns can only be added to existing tables. Trying to add a geometry column to a table that doesn't exist yet might mean you have a schema like `{\"rowid\": int, \"geometry\": bytes}`. Might be worth nudging people to explicitly create a table first, then add geometry columns.\r\n", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/398/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 764059235, "node_id": "MDU6SXNzdWU3NjQwNTkyMzU=", "number": 1143, "title": "More flexible CORS support in core, to encourage good security practices", "user": {"value": 114388, "label": "yurivish"}, "state": "open", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 6, "created_at": "2020-12-12T17:06:35Z", "updated_at": "2022-02-13T17:41:17Z", "closed_at": null, "author_association": "NONE", "pull_request": null, "body": "It would be nice if the `--cors` option accepted an origin regex to more securely allow secure local development.\r\n\r\nAs an example, Observable notebooks namespace every user's notebooks by their username and user content is served from username.observableusercontent.com, so you would set `--cors-origin username.observableusercontent.com` to restrict access to a local development Datasette instance to only your own notebooks, rather than exposing the data to any website that makes a request.\r\n\r\nThank you for all of your work on Datasette!", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1143/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1128120451, "node_id": "I_kwDOCGYnMM5DPcCD", "number": 404, "title": "Add example of `--convert` to the help for `sqlite-utils insert`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2022-02-09T06:49:09Z", "updated_at": "2022-02-09T06:56:35Z", "closed_at": "2022-02-09T06:55:16Z", "author_association": "OWNER", "pull_request": null, "body": "https://sqlite-utils.datasette.io/en/3.23/cli-reference.html#insert would be more useful if it included an example of `--convert` in action.\r\n\r\nI can maybe use an example from https://simonwillison.net/2022/Jan/11/sqlite-utils/", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/404/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1109783030, "node_id": "I_kwDOBm6k_c5CJfH2", "number": 1607, "title": "More detailed information about installed SpatiaLite version", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 2, "created_at": "2022-01-20T21:28:03Z", "updated_at": "2022-02-09T06:42:02Z", "closed_at": "2022-02-09T06:32:28Z", "author_association": "OWNER", "pull_request": null, "body": "https://www.gaia-gis.it/gaia-sins/spatialite-sql-5.0.0.html#version has a whole bunch of interesting functions for things like `freexl_version()` and `geos_version()` and `HasMathSQL()` and suchlike.\r\n\r\nThese could be shown on the `/-/versions` page.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1607/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1126692066, "node_id": "I_kwDOCGYnMM5DJ_Ti", "number": 403, "title": "Document how to add a primary key to a rowid table using `sqlite-utils transform --pk`", "user": {"value": 536941, "label": "fgregg"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2022-02-08T01:39:40Z", "updated_at": "2022-02-09T04:22:43Z", "closed_at": "2022-02-08T19:33:59Z", "author_association": "CONTRIBUTOR", "pull_request": null, "body": "*Original title: Add option for adding a new, serial, primary key*\r\n\r\nsometimes we have tables that don't have primary keys, but ought to have them. we *can* use rowid for that, but it would often be nicer to have an explicit primary key. using the current value of rowid would be fine.", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/403/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1101705012, "node_id": "PR_kwDOBm6k_c4w7eqc", "number": 1593, "title": "Update pytest-asyncio requirement from <0.17,>=0.10 to >=0.10,<0.18", "user": {"value": 49699333, "label": "dependabot[bot]"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2022-01-13T13:11:50Z", "updated_at": "2022-02-07T13:13:24Z", "closed_at": "2022-02-07T13:13:23Z", "author_association": "CONTRIBUTOR", "pull_request": "simonw/datasette/pulls/1593", "body": "Updates the requirements on [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) to permit the latest version.\n
\nRelease notes\n

Sourced from pytest-asyncio's releases.

\n
\n

pytest-asyncio 0.17.0

\n
\n

title: 'pytest-asyncio: pytest support for asyncio'

\n

\"image\"

\n

\"image\"

\n

\"image\"

\n

\"Supported

\n

\"image\"

\n

pytest-asyncio is an Apache2 licensed library, written in Python, for\ntesting asyncio code with pytest.

\n

asyncio code is usually written in the form of coroutines, which makes\nit slightly more difficult to test using normal testing tools.\npytest-asyncio provides useful fixtures and markers to make testing\neasier.

\n
@pytest.mark.asyncio\nasync def test_some_asyncio_code():\n    res = await library.do_something()\n    assert b"expected result" == res\n
\n

pytest-asyncio has been strongly influenced by\npytest-tornado.

\n

Features

\n
    \n
  • fixtures for creating and injecting versions of the asyncio event\nloop
  • \n
  • fixtures for injecting unused tcp/udp ports
  • \n
  • pytest markers for treating tests as asyncio coroutines
  • \n
  • easy testing with non-default event loops
  • \n
  • support for [async def]{.title-ref} fixtures and async generator\nfixtures
  • \n
  • support auto mode to handle all async fixtures and tests\nautomatically by asyncio; provide strict mode if a test suite\nshould work with different async frameworks simultaneously, e.g.\nasyncio and trio.
  • \n
\n

Installation

\n\n
\n

... (truncated)

\n
\n
\nCommits\n\n
\n
\n\n\nDependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.\n\n[//]: # (dependabot-automerge-start)\n[//]: # (dependabot-automerge-end)\n\n---\n\n
\nDependabot commands and options\n
\n\nYou can trigger Dependabot actions by commenting on this PR:\n- `@dependabot rebase` will rebase this PR\n- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it\n- `@dependabot merge` will merge this PR after your CI passes on it\n- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it\n- `@dependabot cancel merge` will cancel a previously requested merge and block automerging\n- `@dependabot reopen` will reopen this PR if it is closed\n- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually\n- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)\n- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)\n- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)\n\n\n
", "repo": {"value": 107914493, "label": "datasette"}, "type": "pull", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1593/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": 0, "state_reason": null} {"id": 779691739, "node_id": "MDU6SXNzdWU3Nzk2OTE3Mzk=", "number": 1176, "title": "Policy on documenting \"public\" datasette.utils functions", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 13, "created_at": "2021-01-05T22:55:25Z", "updated_at": "2022-02-07T06:43:32Z", "closed_at": "2022-02-07T06:42:58Z", "author_association": "OWNER", "pull_request": null, "body": "https://github.com/simonw/datasette-css-properties starts [like this](https://github.com/simonw/datasette-css-properties/blob/0.1/datasette_css_properties/__init__.py#L1-L3):\r\n\r\n```python\r\nfrom datasette import hookimpl\r\nfrom datasette.utils.asgi import Response\r\nfrom datasette.utils import escape_css_string, to_css_class\r\n```\r\n`escape_css_string` and `to_css_class` are not documented, which means relying on them is risky since there's no promise that they won't change.\r\n\r\nWould be good to figure out a policy on this, and maybe promote some of them to \"documented\" status.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1176/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1125576543, "node_id": "I_kwDOBm6k_c5DFu9f", "number": 1630, "title": "Review datasette.utils and decide which functions should be documented for 1.0", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 0, "created_at": "2022-02-07T06:39:52Z", "updated_at": "2022-02-07T06:39:52Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "Follows:\r\n- #1176", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1630/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 688622148, "node_id": "MDU6SXNzdWU2ODg2MjIxNDg=", "number": 957, "title": "Simplify imports of common classes", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 7, "created_at": "2020-08-29T23:44:04Z", "updated_at": "2022-02-06T06:36:41Z", "closed_at": "2022-02-06T06:34:37Z", "author_association": "OWNER", "pull_request": null, "body": "There are only a few classes that plugins need to import. It would be nice if these imports were as short and memorable as possible.\r\n\r\nFor example:\r\n```python\r\nfrom datasette.app import Datasette\r\nfrom datasette.utils.asgi import Response\r\n```\r\nCould both become:\r\n```python\r\nfrom datasette import Datasette\r\nfrom datasette import Response\r\n```\r\n", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/957/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1125081640, "node_id": "I_kwDOCGYnMM5DD2Io", "number": 401, "title": "Update SpatiaLite example in the documentation", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2022-02-06T02:02:07Z", "updated_at": "2022-02-06T02:05:03Z", "closed_at": "2022-02-06T02:03:24Z", "author_association": "OWNER", "pull_request": null, "body": "This one here: https://sqlite-utils.datasette.io/en/3.23/python-api.html#converting-column-values-using-sql-functions\r\n\r\nIt should take advantage of the new methods from:\r\n- #79", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/401/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1125077063, "node_id": "I_kwDOCGYnMM5DD1BH", "number": 400, "title": "`sqlite-utils create-table` ... `--if-not-exists`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-02-06T01:32:53Z", "updated_at": "2022-02-06T01:34:53Z", "closed_at": "2022-02-06T01:34:46Z", "author_association": "OWNER", "pull_request": null, "body": "Inspired by:\r\n- #397\r\n\r\nTo match the option on `create-index`: https://sqlite-utils.datasette.io/en/stable/cli-reference.html#create-index\r\n\r\n```\r\n --if-not-exists Ignore if index already exists\r\n```", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/400/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1123903919, "node_id": "I_kwDOCGYnMM5C_Wmv", "number": 397, "title": "Support IF NOT EXISTS for table creation", "user": {"value": 738408, "label": "rafguns"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2022-02-04T07:41:15Z", "updated_at": "2022-02-06T01:30:46Z", "closed_at": "2022-02-06T01:29:01Z", "author_association": "NONE", "pull_request": null, "body": "Currently, I have a bunch of code that looks like this:\r\n\r\n```python\r\nsubjects = db[\"subjects\"] if db[\"subjects\"].exists() else db[\"subjects\"].create({\r\n ...\r\n})\r\n```\r\nIt would be neat if sqlite-utils could simplify that by supporting `CREATE TABLE IF NOT EXISTS`, so that I'd be able to write, e.g.\r\n\r\n```python\r\nsubjects = db[\"subjects\"].create({...}, if_not_exists=True)\r\n```", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/397/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1087181951, "node_id": "I_kwDOBm6k_c5AzRR_", "number": 1576, "title": "Traces should include SQL executed by subtasks created with `asyncio.gather`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 12, "created_at": "2021-12-22T20:52:02Z", "updated_at": "2022-02-05T05:21:35Z", "closed_at": "2022-02-05T05:19:53Z", "author_association": "OWNER", "pull_request": null, "body": "I tried running some parallel SQL queries using `asyncio.gather()` but the SQL that was executed didn't show up in the trace rendered by https://datasette.io/plugins/datasette-pretty-traces\r\n\r\nI realized that was because traces are keyed against the current task ID, which changes when a sub-task is run using `asyncio.gather` or similar.\r\n\r\nThe faceting and suggest faceting queries are missing from this trace:\r\n\r\n![image](https://user-images.githubusercontent.com/9599/147153855-2d611f07-922a-4d18-9e6e-4be89e010dc4.png)\r\n\r\n> The reason they aren't showing up in the traces is that traces are stored just for the currently executing `asyncio` task ID: https://github.com/simonw/datasette/blob/ace86566b28280091b3844cf5fbecd20158e9004/datasette/tracer.py#L13-L25\r\n>\r\n> This is so traces for other incoming requests don't end up mixed together. But there's no current mechanism to track async tasks that are effectively \"child tasks\" of the current request, and hence should be tracked the same.\r\n>\r\n> https://stackoverflow.com/a/69349501/6083 suggests that you pass the task ID as an argument to the child tasks that are executed using `asyncio.gather()` to work around this kind of problem.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1518#issuecomment-999870993_", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1576/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 683805434, "node_id": "MDU6SXNzdWU2ODM4MDU0MzQ=", "number": 135, "title": "Code for finding SpatiaLite in the usual locations", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2020-08-21T20:15:34Z", "updated_at": "2022-02-05T00:04:26Z", "closed_at": "2020-08-21T20:30:13Z", "author_association": "OWNER", "pull_request": null, "body": "I built this for `shapefile-to-sqlite` but it would be useful in `sqlite-utils` too:\r\n\r\nhttps://github.com/simonw/shapefile-to-sqlite/blob/e754d0747ca2facf9a7433e2d5d15a6a37a9cf6e/shapefile_to_sqlite/utils.py#L16-L19\r\n\r\n```python\r\nSPATIALITE_PATHS = (\r\n \"/usr/lib/x86_64-linux-gnu/mod_spatialite.so\",\r\n \"/usr/local/lib/mod_spatialite.dylib\",\r\n)\r\n```\r\n\r\nhttps://github.com/simonw/shapefile-to-sqlite/blob/e754d0747ca2facf9a7433e2d5d15a6a37a9cf6e/shapefile_to_sqlite/utils.py#L105-L109\r\n\r\n```python\r\ndef find_spatialite():\r\n for path in SPATIALITE_PATHS:\r\n if os.path.exists(path):\r\n return path\r\n return None\r\n```", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/135/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 683812642, "node_id": "MDU6SXNzdWU2ODM4MTI2NDI=", "number": 136, "title": "--load-extension=spatialite shortcut option", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2020-08-21T20:31:25Z", "updated_at": "2022-02-05T00:04:26Z", "closed_at": "2020-10-16T19:14:32Z", "author_association": "OWNER", "pull_request": null, "body": "In conjunction with #135 - this would do the same thing as `--load-extension=path-to-spatialite` (see #134)", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/136/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 723460107, "node_id": "MDU6SXNzdWU3MjM0NjAxMDc=", "number": 187, "title": "Maybe: Utility method / CLI tool for initializing SpatiaLite", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2020-10-16T19:04:03Z", "updated_at": "2022-02-05T00:04:26Z", "closed_at": "2020-10-16T19:15:13Z", "author_association": "OWNER", "pull_request": null, "body": "> I think this should initialize SpatiaLite against the current database if it has not been initialized already.\r\n>\r\n> Relevant code: https://github.com/simonw/shapefile-to-sqlite/blob/e754d0747ca2facf9a7433e2d5d15a6a37a9cf6e/shapefile_to_sqlite/utils.py#L112-L126", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/187/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 723708310, "node_id": "MDU6SXNzdWU3MjM3MDgzMTA=", "number": 188, "title": "About loading spatialite", "user": {"value": 30607, "label": "aborruso"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2020-10-17T08:47:02Z", "updated_at": "2022-02-05T00:04:26Z", "closed_at": "2020-10-17T08:52:58Z", "author_association": "NONE", "pull_request": null, "body": "Hi @simonw ,\r\nIf I run\r\n\r\n```\r\nsqlite3\r\n.load /usr/local/lib/mod_spatialite.so\r\nselect spatialite_version();\r\n```\r\n\r\nI have `5.0.0`.\r\n\r\n![image](https://user-images.githubusercontent.com/30607/96332706-d8cd3300-1065-11eb-906b-daf99963198e.png)\r\n\r\n\r\nIf I run\r\n\r\n```\r\nsqlite-utils :memory: \"select spatialite_version()\" --load-extension=spatialite\r\n```\r\n\r\nI have\r\n\r\n```\r\nTraceback (most recent call last):\r\n File \"/home/aborruso/.local/bin/sqlite-utils\", line 8, in \r\n sys.exit(cli())\r\n File \"/home/aborruso/.local/lib/python3.8/site-packages/click/core.py\", line 829, in __call__\r\n return self.main(*args, **kwargs)\r\n File \"/home/aborruso/.local/lib/python3.8/site-packages/click/core.py\", line 782, in main\r\n rv = self.invoke(ctx)\r\n File \"/home/aborruso/.local/lib/python3.8/site-packages/click/core.py\", line 1259, in invoke\r\n return _process_result(sub_ctx.command.invoke(sub_ctx))\r\n File \"/home/aborruso/.local/lib/python3.8/site-packages/click/core.py\", line 1066, in invoke\r\n return ctx.invoke(self.callback, **ctx.params)\r\n File \"/home/aborruso/.local/lib/python3.8/site-packages/click/core.py\", line 610, in invoke\r\n return callback(*args, **kwargs)\r\n File \"/home/aborruso/.local/lib/python3.8/site-packages/sqlite_utils/cli.py\", line 936, in query\r\n _load_extensions(db, load_extension)\r\n File \"/home/aborruso/.local/lib/python3.8/site-packages/sqlite_utils/cli.py\", line 1326, in _load_extensions\r\n db.conn.load_extension(ext)\r\nTypeError: argument 1 must be str, not None\r\n```\r\n\r\nHow to load properly spatialite extension in sqlite-utils?\r\n\r\nThank you very muc", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/188/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1102899312, "node_id": "PR_kwDOCGYnMM4w_p22", "number": 385, "title": "Add new spatialite helper methods", "user": {"value": 25778, "label": "eyeseast"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 16, "created_at": "2022-01-14T03:57:30Z", "updated_at": "2022-02-05T00:04:26Z", "closed_at": "2022-02-04T05:55:10Z", "author_association": "CONTRIBUTOR", "pull_request": "simonw/sqlite-utils/pulls/385", "body": "Refs #79 \r\n\r\nThis PR adds three new Spatialite-related methods to Database and Table:\r\n\r\n- `Database.init_spatialite` loads the Spatialite extension and initializes it\r\n- `Table.add_geometry_column` adds a geometry column\r\n- `Table.create_spatial_index` creates a spatial index\r\n\r\nHas tests and documentation. Feedback very welcome.", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "pull", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/385/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": 0, "state_reason": null} {"id": 534507142, "node_id": "MDU6SXNzdWU1MzQ1MDcxNDI=", "number": 69, "title": "Feature request: enable extensions loading", "user": {"value": 30607, "label": "aborruso"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2019-12-08T08:06:25Z", "updated_at": "2022-02-05T00:04:25Z", "closed_at": "2020-10-16T18:42:49Z", "author_association": "NONE", "pull_request": null, "body": "Hi, it would be great to add a parameter that enables the load of a sqlite extension you need.\r\n\r\nSomething like \"-ext modspatialite\".\r\n\r\nIn this way your great tool would be even more comfortable and powerful.\r\n\r\n\r\nThank you very much", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/69/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 557825032, "node_id": "MDU6SXNzdWU1NTc4MjUwMzI=", "number": 77, "title": "Ability to insert data that is transformed by a SQL function", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2020-01-30T23:45:55Z", "updated_at": "2022-02-05T00:04:25Z", "closed_at": "2020-01-31T00:24:32Z", "author_association": "OWNER", "pull_request": null, "body": "I want to be able to run the equivalent of this SQL insert:\r\n```python\r\n# Convert to \"Well Known Text\" format\r\nwkt = shape(geojson['geometry']).wkt\r\n# Insert and commit the record\r\nconn.execute(\"INSERT INTO places (id, name, geom) VALUES(null, ?, GeomFromText(?, 4326))\", (\r\n \"Wales\", wkt\r\n))\r\nconn.commit()\r\n```\r\nFrom the Datasette SpatiaLite docs: https://datasette.readthedocs.io/en/stable/spatialite.html\r\n\r\nTo do this, I need a way of telling `sqlite-utils` that a specific column should be wrapped in `GeomFromText(?, 4326)`.", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/77/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 557842245, "node_id": "MDU6SXNzdWU1NTc4NDIyNDU=", "number": 79, "title": "Helper methods for working with SpatiaLite", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 8, "created_at": "2020-01-31T00:39:19Z", "updated_at": "2022-02-05T00:04:25Z", "closed_at": "2022-02-04T05:55:11Z", "author_association": "OWNER", "pull_request": null, "body": "As demonstrated by this piece of documentation, using SpatiaLite with sqlite-utils requires a fair bit of boilerplate:\r\nhttps://github.com/simonw/sqlite-utils/blob/f7289174e66ae4d91d57de94bbd9d09fabf7aff4/docs/python-api.rst#L880-L909", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/79/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 734777631, "node_id": "MDU6SXNzdWU3MzQ3Nzc2MzE=", "number": 1080, "title": "\"View all\" option for facets, to provide a (paginated) list of ALL of the facet counts plus a link to view them", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 7, "created_at": "2020-11-02T19:55:06Z", "updated_at": "2022-02-04T06:25:18Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "Can use `/database/-/...` namespace from #296", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1080/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1123849278, "node_id": "I_kwDOCGYnMM5C_JQ-", "number": 395, "title": "\"apt-get: command not found\" error on macOS", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-02-04T06:03:42Z", "updated_at": "2022-02-04T06:10:58Z", "closed_at": "2022-02-04T06:10:58Z", "author_association": "OWNER", "pull_request": null, "body": "Yeah, `apt-get` isn't a thing on macOS so 4a2a3e2fd0d5534f446b3f1fee34cb165e4d86d2 (to test #79 against real SpatiaLite) broke.", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/395/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1123851690, "node_id": "I_kwDOCGYnMM5C_J2q", "number": 396, "title": "mypy failure, sqlite_utils/utils.py:56", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2022-02-04T06:08:09Z", "updated_at": "2022-02-04T06:10:33Z", "closed_at": "2022-02-04T06:10:33Z", "author_association": "OWNER", "pull_request": null, "body": "https://github.com/simonw/sqlite-utils/runs/5062725880?check_suite_focus=true\r\n\r\n> `sqlite_utils/utils.py:56: error: Incompatible return value type (got \"None\", expected \"str\")`", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/396/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1072792507, "node_id": "I_kwDOCGYnMM4_8YO7", "number": 352, "title": "`sqlite-utils insert --extract colname`", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2021-12-07T00:55:44Z", "updated_at": "2022-02-03T22:59:36Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "Is there a reason I've not added `--extract` as an option for `sqlite-utils insert` next? There's a `extracts=` option for the various `table.insert()` etc methods - last line in this code block:\r\n\r\nhttps://github.com/simonw/sqlite-utils/blob/213a0ff177f23a35f3b235386366ff132eb879f1/sqlite_utils/db.py#L2483-L2495", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/352/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1094981339, "node_id": "I_kwDOCGYnMM5BRBbb", "number": 363, "title": "Better error message if `--convert` code fails to return a dict", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2022-01-06T05:26:28Z", "updated_at": "2022-02-03T22:52:30Z", "closed_at": "2022-02-03T22:51:30Z", "author_association": "OWNER", "pull_request": null, "body": "Here's the traceback if your `--convert` function doesn't return a dict right now:\r\n```\r\n% sqlite-utils insert /tmp/all.db blah /tmp/log.log --convert 'all.upper()' --all \r\n\r\nTraceback (most recent call last):\r\n File \"/Users/simon/.local/share/virtualenvs/sqlite-utils-C4Ilevlm/bin/sqlite-utils\", line 33, in \r\n sys.exit(load_entry_point('sqlite-utils', 'console_scripts', 'sqlite-utils')())\r\n File \"/Users/simon/.local/share/virtualenvs/sqlite-utils-C4Ilevlm/lib/python3.8/site-packages/click/core.py\", line 1137, in __call__\r\n return self.main(*args, **kwargs)\r\n File \"/Users/simon/.local/share/virtualenvs/sqlite-utils-C4Ilevlm/lib/python3.8/site-packages/click/core.py\", line 1062, in main\r\n rv = self.invoke(ctx)\r\n File \"/Users/simon/.local/share/virtualenvs/sqlite-utils-C4Ilevlm/lib/python3.8/site-packages/click/core.py\", line 1668, in invoke\r\n return _process_result(sub_ctx.command.invoke(sub_ctx))\r\n File \"/Users/simon/.local/share/virtualenvs/sqlite-utils-C4Ilevlm/lib/python3.8/site-packages/click/core.py\", line 1404, in invoke\r\n return ctx.invoke(self.callback, **ctx.params)\r\n File \"/Users/simon/.local/share/virtualenvs/sqlite-utils-C4Ilevlm/lib/python3.8/site-packages/click/core.py\", line 763, in invoke\r\n return __callback(*args, **kwargs)\r\n File \"/Users/simon/Dropbox/Development/sqlite-utils/sqlite_utils/cli.py\", line 949, in insert\r\n insert_upsert_implementation(\r\n File \"/Users/simon/Dropbox/Development/sqlite-utils/sqlite_utils/cli.py\", line 834, in insert_upsert_implementation\r\n db[table].insert_all(\r\n File \"/Users/simon/Dropbox/Development/sqlite-utils/sqlite_utils/db.py\", line 2602, in insert_all\r\n first_record = next(records)\r\n File \"/Users/simon/Dropbox/Development/sqlite-utils/sqlite_utils/db.py\", line 3044, in fix_square_braces\r\n for record in records:\r\n File \"/Users/simon/Dropbox/Development/sqlite-utils/sqlite_utils/cli.py\", line 831, in \r\n docs = (decode_base64_values(doc) for doc in docs)\r\n File \"/Users/simon/Dropbox/Development/sqlite-utils/sqlite_utils/utils.py\", line 86, in decode_base64_values\r\n to_fix = [\r\n File \"/Users/simon/Dropbox/Development/sqlite-utils/sqlite_utils/utils.py\", line 89, in \r\n if isinstance(doc[k], dict)\r\nTypeError: string indices must be integers\r\n```\r\nIt would be nicer if that returned a more useful error message.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/sqlite-utils/issues/361#issuecomment-1006295276_", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/363/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1118585417, "node_id": "I_kwDOCGYnMM5CrEJJ", "number": 393, "title": "Better documentation for insert-replace", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-01-30T15:40:23Z", "updated_at": "2022-02-03T22:13:24Z", "closed_at": "2022-02-03T22:13:24Z", "author_association": "OWNER", "pull_request": null, "body": "Currently: https://sqlite-utils.datasette.io/en/stable/python-api.html#insert-replacing-data\r\n\r\n> If you want to insert a record or replace an existing record with the same primary key, using the replace=True argument to .insert() or .insert_all():\r\n\r\nShould describe the exception you get first, then how to use replace to avoid it.", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/393/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1097091527, "node_id": "I_kwDOCGYnMM5BZEnH", "number": 369, "title": "Research how much of a difference analyze / sqlite_stat1 makes", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 11, "created_at": "2022-01-09T03:03:36Z", "updated_at": "2022-02-03T21:07:41Z", "closed_at": "2022-02-03T21:07:35Z", "author_association": "OWNER", "pull_request": null, "body": "> Is there a downside to having a `sqlite_stat1` table if it has wildly incorrect statistics in it?\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/sqlite-utils/issues/365#issuecomment-1008163050_\r\n\r\nMore generally: how much of a difference does the `sqlite_stat1` table created by `ANALYZE` make to queries?\r\n\r\nI'm particularly interested in `group by` / `count *` queries since Datasette uses those for faceting.", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/369/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1122446693, "node_id": "I_kwDOCGYnMM5C5y1l", "number": 394, "title": "Test against Python 3.11-dev", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-02-02T22:21:03Z", "updated_at": "2022-02-03T21:06:35Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "Same as:\r\n- https://github.com/simonw/datasette/issues/1621", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/394/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1075893249, "node_id": "I_kwDOBm6k_c5AINQB", "number": 1545, "title": "Custom pages don't work on windows", "user": {"value": 559711, "label": "ryascott"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2021-12-09T18:53:05Z", "updated_at": "2022-02-03T02:08:31Z", "closed_at": "2022-02-03T01:58:35Z", "author_association": "NONE", "pull_request": null, "body": "It seems that custom pages don't work when put in templates/pages\r\n\r\nTo reproduce on datasette version 0.59.4 using PowerShell on WIndows 10 with Python 3.10.0\r\n\r\n mkdir -p templates/pages\r\n\r\n echo \"hello world\" >> templates/pages/about.html\r\n\r\nStart datasette\r\n \r\n datasette --template-dir templates/\r\n\r\nNavigate to [http://127.0.0.1:8001/about](url) and receive:\r\n \r\n Error 404:\r\n Database not found: about\r\n\r\n\r\n\r\n\r\n\r\n", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1545/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1120990806, "node_id": "PR_kwDOBm6k_c4x6zZ5", "number": 1617, "title": "Ensure template_path always uses \"/\" to match jinja", "user": {"value": 3526913, "label": "cb160"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2022-02-01T17:20:30Z", "updated_at": "2022-02-03T01:58:35Z", "closed_at": "2022-02-03T01:58:35Z", "author_association": "CONTRIBUTOR", "pull_request": "simonw/datasette/pulls/1617", "body": "This PR shoudl fix #1545 \r\n\r\nThe existing code substituted / for \\, assuming this was the right behaviour for windows. But on Windows, Jinja still uses / for the template list - See https://github.com/pallets/jinja/blob/896a62135bcc151f2997e028c5125bec2cb2431f/src/jinja2/loaders.py#L225", "repo": {"value": 107914493, "label": "datasette"}, "type": "pull", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1617/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": 0, "state_reason": null} {"id": 1122557010, "node_id": "I_kwDOBm6k_c5C6NxS", "number": 1627, "title": "Get the tests passing against Windows", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2022-02-03T01:23:06Z", "updated_at": "2022-02-03T01:23:32Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "> OK, the tests do NOT pass against Windows! https://github.com/simonw/datasette/runs/5044105941\r\n>\r\n> \"image\"\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1626#issuecomment-1028515161_", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1627/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1122451096, "node_id": "PR_kwDOBm6k_c4x_mXy", "number": 1626, "title": "Try test suite against macOS and Windows", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2022-02-02T22:26:51Z", "updated_at": "2022-02-03T01:22:44Z", "closed_at": null, "author_association": "OWNER", "pull_request": "simonw/datasette/pulls/1626", "body": "Refs #1625", "repo": {"value": 107914493, "label": "datasette"}, "type": "pull", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1626/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": 0, "state_reason": null} {"id": 1122450452, "node_id": "I_kwDOBm6k_c5C5zwU", "number": 1625, "title": "Try running tests against macOS and Windows in addition to Ubuntu", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2022-02-02T22:25:57Z", "updated_at": "2022-02-02T22:25:57Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "I already do this for `sqlite-utils`: https://github.com/simonw/sqlite-utils/blob/3.22.1/.github/workflows/test.yml\r\n\r\nRelated:\r\n- #1617\r\n- #1545", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1625/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1119413338, "node_id": "PR_kwDOBm6k_c4x1kCu", "number": 1616, "title": "Bump black from 21.12b0 to 22.1.0", "user": {"value": 49699333, "label": "dependabot[bot]"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2022-01-31T13:13:46Z", "updated_at": "2022-02-02T22:23:52Z", "closed_at": "2022-02-02T22:23:51Z", "author_association": "CONTRIBUTOR", "pull_request": "simonw/datasette/pulls/1616", "body": "Bumps [black](https://github.com/psf/black) from 21.12b0 to 22.1.0.\n
\nRelease notes\n

Sourced from black's releases.

\n
\n

22.1.0

\n

At long last, Black is no longer a beta product! This is the first non-beta release and the first release covered by our new stability policy.

\n

Highlights

\n
    \n
  • Remove Python 2 support (#2740)
  • \n
  • Introduce the --preview flag (#2752)
  • \n
\n

Style

\n
    \n
  • Deprecate --experimental-string-processing and move the functionality under --preview (#2789)
  • \n
  • For stubs, one blank line between class attributes and methods is now kept if there's at least one pre-existing blank line (#2736)
  • \n
  • Black now normalizes string prefix order (#2297)
  • \n
  • Remove spaces around power operators if both operands are simple (#2726)
  • \n
  • Work around bug that causes unstable formatting in some cases in the presence of the magic trailing comma (#2807)
  • \n
  • Use parentheses for attribute access on decimal float and int literals (#2799)
  • \n
  • Don't add whitespace for attribute access on hexadecimal, binary, octal, and complex literals (#2799)
  • \n
  • Treat blank lines in stubs the same inside top-level if statements (#2820)
  • \n
  • Fix unstable formatting with semicolons and arithmetic expressions (#2817)
  • \n
  • Fix unstable formatting around magic trailing comma (#2572)
  • \n
\n

Parser

\n
    \n
  • Fix mapping cases that contain as-expressions, like case {"key": 1 | 2 as password} (#2686)
  • \n
  • Fix cases that contain multiple top-level as-expressions, like case 1 as a, 2 as b (#2716)
  • \n
  • Fix call patterns that contain as-expressions with keyword arguments, like case Foo(bar=baz as quux) (#2749)
  • \n
  • Tuple unpacking on return and yield constructs now implies 3.8+ (#2700)
  • \n
  • Unparenthesized tuples on annotated assignments (e.g values: Tuple[int, ...] = 1, 2, 3) now implies 3.8+ (#2708)
  • \n
  • Fix handling of standalone match() or case() when there is a trailing newline or a comment inside of the parentheses. (#2760)
  • \n
  • from __future__ import annotations statement now implies Python 3.7+ (#2690)
  • \n
\n

Performance

\n
    \n
  • Speed-up the new backtracking parser about 4X in general (enabled when --target-version is set to 3.10 and higher). (#2728)
  • \n
  • Black is now compiled with mypyc for an overall 2x speed-up. 64-bit Windows, MacOS, and Linux (not including musl) are supported. (#1009, #2431)
  • \n
\n

Configuration

\n
    \n
  • Do not accept bare carriage return line endings in pyproject.toml (#2408)
  • \n
  • Add configuration option (python-cell-magics) to format cells with custom magics in Jupyter Notebooks (#2744)
  • \n
  • Allow setting custom cache directory on all platforms with environment variable BLACK_CACHE_DIR (#2739).
  • \n
  • Enable Python 3.10+ by default, without any extra need to specify --target-version=py310. (#2758)
  • \n
  • Make passing SRC or --code mandatory and mutually exclusive (#2804)
  • \n
\n

Output

\n
    \n
  • Improve error message for invalid regular expression (#2678)
  • \n
  • Improve error message when parsing fails during AST safety check by embedding the underlying SyntaxError (#2693)
  • \n
  • No longer color diff headers white as it's unreadable in light themed terminals (#2691)
  • \n
  • Text coloring added in the final statistics (#2712)
  • \n
  • Verbose mode also now describes how a project root was discovered and which paths will be formatted. (#2526)
  • \n
\n

Packaging

\n
    \n
  • All upper version bounds on dependencies have been removed (#2718)
  • \n
  • typing-extensions is no longer a required dependency in Python 3.10+ (#2772)
  • \n
  • Set click lower bound to 8.0.0 as Black crashes on 7.1.2 (#2791)
  • \n
\n\n
\n

... (truncated)

\n
\n
\nChangelog\n

Sourced from black's changelog.

\n
\n

22.1.0

\n

At long last, Black is no longer a beta product! This is the first non-beta release\nand the first release covered by our new stability policy.

\n

Highlights

\n
    \n
  • Remove Python 2 support (#2740)
  • \n
  • Introduce the --preview flag (#2752)
  • \n
\n

Style

\n
    \n
  • Deprecate --experimental-string-processing and move the functionality under\n--preview (#2789)
  • \n
  • For stubs, one blank line between class attributes and methods is now kept if there's\nat least one pre-existing blank line (#2736)
  • \n
  • Black now normalizes string prefix order (#2297)
  • \n
  • Remove spaces around power operators if both operands are simple (#2726)
  • \n
  • Work around bug that causes unstable formatting in some cases in the presence of the\nmagic trailing comma (#2807)
  • \n
  • Use parentheses for attribute access on decimal float and int literals (#2799)
  • \n
  • Don't add whitespace for attribute access on hexadecimal, binary, octal, and complex\nliterals (#2799)
  • \n
  • Treat blank lines in stubs the same inside top-level if statements (#2820)
  • \n
  • Fix unstable formatting with semicolons and arithmetic expressions (#2817)
  • \n
  • Fix unstable formatting around magic trailing comma (#2572)
  • \n
\n

Parser

\n
    \n
  • Fix mapping cases that contain as-expressions, like case {"key": 1 | 2 as password}\n(#2686)
  • \n
  • Fix cases that contain multiple top-level as-expressions, like case 1 as a, 2 as b\n(#2716)
  • \n
  • Fix call patterns that contain as-expressions with keyword arguments, like\ncase Foo(bar=baz as quux) (#2749)
  • \n
  • Tuple unpacking on return and yield constructs now implies 3.8+ (#2700)
  • \n
  • Unparenthesized tuples on annotated assignments (e.g\nvalues: Tuple[int, ...] = 1, 2, 3) now implies 3.8+ (#2708)
  • \n
  • Fix handling of standalone match() or case() when there is a trailing newline or a\ncomment inside of the parentheses. (#2760)
  • \n
  • from __future__ import annotations statement now implies Python 3.7+ (#2690)
  • \n
\n

Performance

\n
    \n
  • Speed-up the new backtracking parser about 4X in general (enabled when\n--target-version is set to 3.10 and higher). (#2728)
  • \n
  • Black is now compiled with mypyc for an overall 2x\nspeed-up. 64-bit Windows, MacOS, and Linux (not including musl) are supported. (#1009,\n#2431)
  • \n
\n\n
\n

... (truncated)

\n
\n
\nCommits\n\n
\n
\n\n\n[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=black&package-manager=pip&previous-version=21.12b0&new-version=22.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)\n\nDependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.\n\n[//]: # (dependabot-automerge-start)\n[//]: # (dependabot-automerge-end)\n\n---\n\n
\nDependabot commands and options\n
\n\nYou can trigger Dependabot actions by commenting on this PR:\n- `@dependabot rebase` will rebase this PR\n- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it\n- `@dependabot merge` will merge this PR after your CI passes on it\n- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it\n- `@dependabot cancel merge` will cancel a previously requested merge and block automerging\n- `@dependabot reopen` will reopen this PR if it is closed\n- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually\n- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)\n- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)\n- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)\n\n\n
", "repo": {"value": 107914493, "label": "datasette"}, "type": "pull", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1616/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": 0, "state_reason": null} {"id": 1122414274, "node_id": "PR_kwDOBm6k_c4x_evE", "number": 1622, "title": "Test against Python 3.11-dev", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-02-02T21:39:38Z", "updated_at": "2022-02-02T21:58:53Z", "closed_at": "2022-02-02T21:58:53Z", "author_association": "OWNER", "pull_request": "simonw/datasette/pulls/1622", "body": "Refs #1621", "repo": {"value": 107914493, "label": "datasette"}, "type": "pull", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1622/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": 0, "state_reason": null} {"id": 1121618041, "node_id": "I_kwDOBm6k_c5C2oh5", "number": 1620, "title": "Link: rel=\"alternate\" to JSON for queries too", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 3, "created_at": "2022-02-02T08:02:42Z", "updated_at": "2022-02-02T21:53:02Z", "closed_at": "2022-02-02T21:33:00Z", "author_association": "OWNER", "pull_request": null, "body": "Following:\r\n- #1533\r\n\r\nI implemented it for tables and rows but I should have done queries as well.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1620/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1121121305, "node_id": "I_kwDOBm6k_c5C0vQZ", "number": 1618, "title": "Reconsider policy on blocking queries containing the string \"pragma\"", "user": {"value": 770231, "label": "strada"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 6, "created_at": "2022-02-01T19:39:46Z", "updated_at": "2022-02-02T19:42:03Z", "closed_at": null, "author_association": "NONE", "pull_request": null, "body": "First of all, thanks for creating this cool project, and also supporting publishing to various hosting services out of the box.\r\n\r\nWhile testing out, I noticed legitimate queries such as \r\n```\r\nselect * from books where title like 'Pragmatic%'\r\n```\r\nor\r\n```\r\nselect * from books where title = 'The Pragmatic Programmer'\r\n```\r\nare blocked, due to the regular expression check here:\r\nhttps://github.com/simonw/datasette/blob/main/datasette/utils/__init__.py#L185\r\n\r\nExample as seen from a Datasette instance:\r\nhttps://fivethirtyeight.datasettes.com/polls?sql=select+*+from+books+where+title+like+%27Pragmatic%25%27%0D%0A\r\n\r\nI'd propose a regular expression like \r\n```\r\nre.compile(f\"pragma_(?!({'|'.join(allowed_pragmas)}))\"),\r\n```\r\ninstead of\r\n```\r\nre.compile(f\"pragma(?!_({'|'.join(allowed_pragmas)}))\"),\r\n```\r\n\r\nI can create a pull request with this change, unless the maintainers think it would allow unwanted queries to be executed.\r\n", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1618/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1065431383, "node_id": "I_kwDOBm6k_c4_gTFX", "number": 1533, "title": "Add `Link: rel=\"alternate\"` header pointing to JSON for a table/query", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 4, "created_at": "2021-11-28T20:43:25Z", "updated_at": "2022-02-02T07:56:51Z", "closed_at": "2022-02-02T07:49:33Z", "author_association": "OWNER", "pull_request": null, "body": "Originally explored in https://github.com/simonw/datasette-notebook/issues/2#issuecomment-980789406 - I wanted an efficient way to scan a list of URLs and figure out which if any of those corresponded to Datasette tables, canned queries or SQL output that could be represented as a table on a page.\r\n\r\nIt looks like a neat way to do that is with ` Link:` header like this:\r\n\r\n`Link: http://127.0.0.1:8058/fixtures/compound_three_primary_keys.json; rel=\"alternate\"; type=\"application/datasette+json\"`\r\n\r\nI can put a `\r\n\r\nLooks like running `count(*)` against KNN took 83s! It ignored the time limit. And still only returned a count of 0.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1611/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1114640101, "node_id": "I_kwDOCGYnMM5CcA7l", "number": 392, "title": "`sqlite-utils bulk --batch-size` option", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2022-01-26T05:17:11Z", "updated_at": "2022-01-26T18:17:59Z", "closed_at": "2022-01-26T18:17:59Z", "author_association": "OWNER", "pull_request": null, "body": "> Could add support for `--batch-size` as seen in `insert`/`upsert` too - causing it to break the list up into batches and commit for each one.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/sqlite-utils/issues/391#issuecomment-1021876055_", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/392/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1114628238, "node_id": "I_kwDOBm6k_c5Cb-CO", "number": 1613, "title": "Improvements to help make Datasette a better tool for learning SQL", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 5, "created_at": "2022-01-26T04:56:07Z", "updated_at": "2022-01-26T16:41:46Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "Tracking issue for the general goal of making Datasette a better tool for learning SQL.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1613/reactions\", \"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1114638930, "node_id": "I_kwDOCGYnMM5CcApS", "number": 391, "title": "`sqlite-utils bulk` progress bar", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2022-01-26T05:14:49Z", "updated_at": "2022-01-26T05:17:20Z", "closed_at": "2022-01-26T05:16:51Z", "author_association": "OWNER", "pull_request": null, "body": "It can easily have a progress bar because it works by looping through an iterator: https://github.com/simonw/sqlite-utils/blob/a9fca7efa4184fbb2a65ca1275c326950ed9d3c1/sqlite_utils/cli.py#L1014-L1018\r\n\r\nShould also support the `--silent` option if I add this.", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/391/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1114557284, "node_id": "I_kwDOCGYnMM5Cbstk", "number": 390, "title": "`sqlite-utils upsert` should require `--pk` more elegantly", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-01-26T02:20:31Z", "updated_at": "2022-01-26T03:20:25Z", "closed_at": "2022-01-26T03:19:43Z", "author_association": "OWNER", "pull_request": null, "body": "Currently throws an ugly traceback:\r\n```\r\n% echo '[\r\n {\"id\": 1, \"name\": \"Lila\"},\r\n {\"id\": 1, \"name\": \"Lila\"}\r\n ]' | sqlite-utils upsert data.db chickens - \r\nTraceback (most recent call last):\r\n File \"/Users/simon/.local/share/virtualenvs/sqlite-utils-C4Ilevlm/bin/sqlite-utils\", line 33, in \r\n sys.exit(load_entry_point('sqlite-utils', 'console_scripts', 'sqlite-utils')())\r\n File \"/Users/simon/.local/share/virtualenvs/sqlite-utils-C4Ilevlm/lib/python3.8/site-packages/click/core.py\", line 1137, in __call__\r\n return self.main(*args, **kwargs)\r\n File \"/Users/simon/.local/share/virtualenvs/sqlite-utils-C4Ilevlm/lib/python3.8/site-packages/click/core.py\", line 1062, in main\r\n rv = self.invoke(ctx)\r\n File \"/Users/simon/.local/share/virtualenvs/sqlite-utils-C4Ilevlm/lib/python3.8/site-packages/click/core.py\", line 1668, in invoke\r\n return _process_result(sub_ctx.command.invoke(sub_ctx))\r\n File \"/Users/simon/.local/share/virtualenvs/sqlite-utils-C4Ilevlm/lib/python3.8/site-packages/click/core.py\", line 1404, in invoke\r\n return ctx.invoke(self.callback, **ctx.params)\r\n File \"/Users/simon/.local/share/virtualenvs/sqlite-utils-C4Ilevlm/lib/python3.8/site-packages/click/core.py\", line 763, in invoke\r\n return __callback(*args, **kwargs)\r\n File \"/Users/simon/Dropbox/Development/sqlite-utils/sqlite_utils/cli.py\", line 1104, in upsert\r\n insert_upsert_implementation(\r\n File \"/Users/simon/Dropbox/Development/sqlite-utils/sqlite_utils/cli.py\", line 906, in insert_upsert_implementation\r\n db[table].insert_all(\r\n File \"/Users/simon/Dropbox/Development/sqlite-utils/sqlite_utils/db.py\", line 2615, in insert_all\r\n raise PrimaryKeyRequired(\"upsert() requires a pk\")\r\nsqlite_utils.db.PrimaryKeyRequired: upsert() requires a pk\r\n```", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/390/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1099897648, "node_id": "I_kwDOCGYnMM5Bjxsw", "number": 384, "title": "Add examples to every `--help`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2022-01-12T05:31:25Z", "updated_at": "2022-01-26T03:15:02Z", "closed_at": "2022-01-26T03:15:02Z", "author_association": "OWNER", "pull_request": null, "body": "Everything on https://sqlite-utils.datasette.io/en/stable/cli-reference.html would benefit from an example.", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/384/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 471818939, "node_id": "MDU6SXNzdWU0NzE4MTg5Mzk=", "number": 48, "title": "Jupyter notebook demo of the library, launchable on Binder", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2019-07-23T17:05:05Z", "updated_at": "2022-01-26T02:08:46Z", "closed_at": "2022-01-26T02:08:39Z", "author_association": "OWNER", "pull_request": null, "body": "", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/48/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1114544727, "node_id": "I_kwDOCGYnMM5CbppX", "number": 389, "title": "Plausible analytics for documentation", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2022-01-26T01:58:35Z", "updated_at": "2022-01-26T02:07:41Z", "closed_at": "2022-01-26T02:07:41Z", "author_association": "OWNER", "pull_request": null, "body": "```html\r\n\r\n```\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/sqlite-utils/issues/388#issuecomment-1021785268_", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/389/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1111293050, "node_id": "I_kwDOCGYnMM5CPPx6", "number": 387, "title": "Python library docs should start with a self contained example", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-01-22T06:23:56Z", "updated_at": "2022-01-26T01:37:17Z", "closed_at": "2022-01-26T01:35:30Z", "author_association": "OWNER", "pull_request": null, "body": "You have to read a lot of stuff in a lot of different places to get started with the Python library. Add a getting started introduction to https://sqlite-utils.datasette.io/en/stable/python-api.html", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/387/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1087913724, "node_id": "I_kwDOBm6k_c5A2D78", "number": 1577, "title": "Drop support for Python 3.6", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 6, "created_at": "2021-12-23T18:17:03Z", "updated_at": "2022-01-25T23:30:03Z", "closed_at": "2022-01-20T04:31:41Z", "author_association": "OWNER", "pull_request": null, "body": "*Original title: Decide when to drop support for Python 3.6*\r\n\r\n> `context_vars` can solve this but they were introduced in Python 3.7: https://www.python.org/dev/peps/pep-0567/\r\n>\r\n> Python 3.6 support ends in a few days time, and it looks like Glitch has updated to 3.7 now - so maybe I can get away with Datasette needing 3.7 these days?\r\n>\r\n> Tweeted about that here: https://twitter.com/simonw/status/1473761478155010048\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1576#issuecomment-999878907_", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1577/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1109884720, "node_id": "I_kwDOBm6k_c5CJ38w", "number": 1609, "title": "Ensure \"pip install datasette\" still works with Python 3.6", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 12, "created_at": "2022-01-21T00:08:10Z", "updated_at": "2022-01-24T19:20:09Z", "closed_at": "2022-01-21T02:24:13Z", "author_association": "OWNER", "pull_request": null, "body": "## Original title: Can I keep \"pip install datasette\" working on Python 3.6?\r\n\r\nI dropped support for 3.6 in:\r\n- #1577\r\n\r\nI'm getting reports that `pip3 install datasette` throws an error on that Python, even though I haven't made that new release yet - presumably due to lack of pinning of Uvicorn: https://twitter.com/ldodds/status/1484289475195080706\r\n\r\nIs it possible to get `pip` on that version of Python to install the highest possible version of the packages that are still known to support Python 3.6?\r\n\r\nIf so, how?", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1609/reactions\", \"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1105916061, "node_id": "I_kwDOBm6k_c5B6vCd", "number": 1601, "title": "Add KNN and data_licenses to hidden tables list", "user": {"value": 25778, "label": "eyeseast"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 5, "created_at": "2022-01-17T14:19:57Z", "updated_at": "2022-01-20T21:29:44Z", "closed_at": "2022-01-20T04:38:54Z", "author_association": "CONTRIBUTOR", "pull_request": null, "body": "They're generated by Spatialite and not very interesting in most cases.\r\n\r\n\"Screen\r\n\r\n", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1601/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 824064069, "node_id": "MDU6SXNzdWU4MjQwNjQwNjk=", "number": 1249, "title": "Updated Dockerfile with SpatiaLite version 5.0", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 45, "created_at": "2021-03-08T00:17:36Z", "updated_at": "2022-01-20T21:29:43Z", "closed_at": "2021-03-29T00:57:13Z", "author_association": "OWNER", "pull_request": null, "body": "The version bundled in Datasette's Docker image right now is 4.4.0-RC0\r\n\r\nhttps://github.com/simonw/datasette/blob/d0fd833b8cdd97e1b91d0f97a69b494895d82bee/Dockerfile#L16-L17\r\n\r\n5 has been out for a couple of months and has a bunch of big improvements, most notable stable KNN support.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1249/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 837308703, "node_id": "MDU6SXNzdWU4MzczMDg3MDM=", "number": 1268, "title": "Figure out why SpatiaLite 5.0 hangs the database page on Linux", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 18, "created_at": "2021-03-22T04:44:16Z", "updated_at": "2022-01-20T21:29:43Z", "closed_at": "2021-03-22T17:41:12Z", "author_association": "OWNER", "pull_request": null, "body": "See detailed notes in https://github.com/simonw/datasette/issues/1249 - for some reason SpatiaLite 5.0 hangs the `/dbname` page on Linux (inside Docker containers, both with a custom compiled SpatiaLite and one installed from the Ubuntu 20.10 package repository). This doesn't happen on macOS with SpatiaLite 5 installed using Homebrew.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1268/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 842416110, "node_id": "MDU6SXNzdWU4NDI0MTYxMTA=", "number": 1278, "title": "SpatiaLite timezones demo is broken", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2021-03-27T04:45:27Z", "updated_at": "2022-01-20T21:29:43Z", "closed_at": "2021-03-27T16:17:13Z", "author_association": "OWNER", "pull_request": null, "body": "https://github.com/simonw/datasette/blob/5fd02890650db790b2ffdb90eb9f78f8e0639c37/docs/spatialite.rst#L96", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1278/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1083581011, "node_id": "I_kwDOBm6k_c5AliJT", "number": 1564, "title": "_prepare_connection not called on write connections", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 1, "created_at": "2021-12-17T20:06:47Z", "updated_at": "2022-01-20T21:29:43Z", "closed_at": "2021-12-18T01:58:44Z", "author_association": "OWNER", "pull_request": null, "body": "I was trying to initalize SpatiaLite in a write connection:\r\n```pycon\r\n>>> from datasette.app import Datasette\r\n>>> ds = Datasette(memory=True, files=[], sqlite_extensions=[\"spatialite\"])\r\n>>> db = ds.add_memory_database('geo')\r\n>>> await db.execute_write(\"select InitSpatialMetadata(1)\")\r\nUUID('3f143baa-4e3d-5842-a36f-4fa2f683b72f')\r\nno such function: InitSpatialMetadata\r\n```\r\nIt looks like the code that loads additional modules only works on read-only connections, not on write connections:\r\n\r\nhttps://github.com/simonw/datasette/blob/92a5280d2e75c39424a75ad6226fc74400ae984f/datasette/database.py#L146-L153\r\n\r\nCompared to:\r\n\r\nhttps://github.com/simonw/datasette/blob/92a5280d2e75c39424a75ad6226fc74400ae984f/datasette/database.py#L124-L132", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1564/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 752966476, "node_id": "MDU6SXNzdWU3NTI5NjY0NzY=", "number": 1114, "title": "--load-extension=spatialite not working with datasetteproject/datasette docker image", "user": {"value": 2182, "label": "danp"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2020-11-29T17:35:20Z", "updated_at": "2022-01-20T21:29:42Z", "closed_at": "2020-11-29T17:37:45Z", "author_association": "CONTRIBUTOR", "pull_request": null, "body": "https://github.com/simonw/datasette/commit/6aa5886379dd9017215904fb28567b80018902f9 added the `--load-extension=spatialite` shortcut looking for the extension in these places:\r\n\r\nhttps://github.com/simonw/datasette/blob/12877d7a48e2aa28bb5e780f929a218f7265d849/datasette/utils/__init__.py#L56-L60\r\n\r\nHowever, in the datasetteproject/datasette docker image the file is at `/usr/local/lib/mod_spatialite.so`.\r\n\r\nThis results in the example command [here](https://docs.datasette.io/en/stable/installation.html#loading-spatialite) failing:\r\n\r\n```\r\n% docker run --rm -p 8001:8001 -v `pwd`:/mnt datasetteproject/datasette datasette -p 8001 -h 0.0.0.0 /mnt/data.db --load-extension=spatialite\r\nError: Could not find SpatiaLite extension\r\n```\r\n\r\nBut it does work when given an explicit path:\r\n\r\n```\r\n% docker run --rm -p 8001:8001 -v `pwd`:/mnt datasetteproject/datasette datasette -p 8001 -h 0.0.0.0 /mnt/data.db --load-extension=/usr/local/lib/mod_spatialite.so\r\nINFO: Started server process [1]\r\nINFO: Waiting for application startup.\r\nINFO: Application startup complete.\r\nINFO: Uvicorn running on http://0.0.0.0:8001 (Press CTRL+C to quit)\r\n...\r\n```\r\n\r\nPerhaps `SPATIALITE_PATHS` should include `/usr/local/lib/mod_spatialite.so`?", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1114/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 752995227, "node_id": "MDU6SXNzdWU3NTI5OTUyMjc=", "number": 1115, "title": "SpatiaLite error could suggest --load-extension=spatialite", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2020-11-29T20:05:07Z", "updated_at": "2022-01-20T21:29:42Z", "closed_at": "2020-11-29T20:13:22Z", "author_association": "OWNER", "pull_request": null, "body": "https://github.com/simonw/datasette/blob/242bc89fdf2e775e340d69a4e851b3a9accb31c6/datasette/cli.py#L533-L548\r\n\r\nThis could use the `find_spatialite()` function and, if it finds something, suggest the user use `--load-extension=spatialite`\r\n\r\nhttps://github.com/simonw/datasette/blob/242bc89fdf2e775e340d69a4e851b3a9accb31c6/datasette/utils/__init__.py#L1015-L1019", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1115/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 443040665, "node_id": "MDU6SXNzdWU0NDMwNDA2NjU=", "number": 466, "title": "Move \"no such module: VirtualSpatialIndex\" code elsewhere", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 4305096, "label": "0.28"}, "comments": 2, "created_at": "2019-05-11T22:09:00Z", "updated_at": "2022-01-20T21:29:41Z", "closed_at": "2019-05-11T22:57:22Z", "author_association": "OWNER", "pull_request": null, "body": "We currently show a useful warning (from #331) when the user tries to open a spatialite database without first loading the module:\r\n\r\nhttps://github.com/simonw/datasette/blob/c692cd291111050483a32bea1ee08e994a0b781b/datasette/app.py#L547-L554\r\n\r\nThis code is part of `.inspect()` which is going away - see #462 - so I need to find somewhere else for it to live.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/466/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 563347679, "node_id": "MDU6SXNzdWU1NjMzNDc2Nzk=", "number": 668, "title": "Make it easier to load SpatiaLite", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2020-02-11T17:03:43Z", "updated_at": "2022-01-20T21:29:41Z", "closed_at": "2021-01-04T20:18:39Z", "author_association": "OWNER", "pull_request": null, "body": "```\r\n$ datasette spatial.db \r\nServe! files=('spatial.db',) (immutables=()) on port 8001\r\nERROR: conn=, sql = 'PRAGMA table_info(SpatialIndex);', params = None: no such module: VirtualSpatialIndex\r\nUsage: datasette serve [OPTIONS] [FILES]...\r\n\r\nError: It looks like you're trying to load a SpatiaLite database without first loading the SpatiaLite module.\r\n\r\nRead more: https://datasette.readthedocs.io/en/latest/spatialite.html\r\n```\r\nThis error message could sniff around in the common locations for the SpatiaLite module and output the CLI command you should use to enable it:\r\n```\r\ndatasette spatial.db --load-extension=/usr/local/lib/mod_spatialite.dylib\r\n```\r\nEven better: if Datasette had a `--spatialite` option which automatically loads the extension from common locations, if it can find it.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/668/reactions\", \"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 723803777, "node_id": "MDU6SXNzdWU3MjM4MDM3Nzc=", "number": 1028, "title": "--load-extension=spatialite shortcut", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 6026070, "label": "0.51"}, "comments": 1, "created_at": "2020-10-17T17:02:08Z", "updated_at": "2022-01-20T21:29:41Z", "closed_at": "2020-10-19T22:37:55Z", "author_association": "OWNER", "pull_request": null, "body": "I added this to `sqlite-utils` in https://github.com/simonw/sqlite-utils/issues/136 and I really like it: pass a special value of `spatialite` and Datasette should attempt to load it from known likely installation locations.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1028/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 336936010, "node_id": "MDU6SXNzdWUzMzY5MzYwMTA=", "number": 331, "title": "Datasette throws error when loading spatialite db without extension loaded", "user": {"value": 82988, "label": "psychemedia"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2018-06-29T09:51:14Z", "updated_at": "2022-01-20T21:29:40Z", "closed_at": "2018-07-10T15:13:36Z", "author_association": "CONTRIBUTOR", "pull_request": null, "body": "When starting datasette on a SpatialLite database *without* loading the SpatiaLite extension (using eg `--load-extension=/usr/local/lib/mod_spatialite.dylib`) an error is thrown and the server fails to start:\r\n\r\n```\r\ndatasette -p 8003 adminboundaries.db \r\nServe! files=('adminboundaries.db',) on port 8003\r\nTraceback (most recent call last):\r\n File \"/Users/ajh59/anaconda3/bin/datasette\", line 11, in \r\n sys.exit(cli())\r\n File \"/Users/ajh59/anaconda3/lib/python3.6/site-packages/click/core.py\", line 722, in __call__\r\n return self.main(*args, **kwargs)\r\n File \"/Users/ajh59/anaconda3/lib/python3.6/site-packages/click/core.py\", line 697, in main\r\n rv = self.invoke(ctx)\r\n File \"/Users/ajh59/anaconda3/lib/python3.6/site-packages/click/core.py\", line 1066, in invoke\r\n return _process_result(sub_ctx.command.invoke(sub_ctx))\r\n File \"/Users/ajh59/anaconda3/lib/python3.6/site-packages/click/core.py\", line 895, in invoke\r\n return ctx.invoke(self.callback, **ctx.params)\r\n File \"/Users/ajh59/anaconda3/lib/python3.6/site-packages/click/core.py\", line 535, in invoke\r\n return callback(*args, **kwargs)\r\n File \"/Users/ajh59/anaconda3/lib/python3.6/site-packages/datasette/cli.py\", line 552, in serve\r\n ds.inspect()\r\n File \"/Users/ajh59/anaconda3/lib/python3.6/site-packages/datasette/app.py\", line 273, in inspect\r\n \"tables\": inspect_tables(conn, self.metadata.get(\"databases\", {}).get(name, {}))\r\n File \"/Users/ajh59/anaconda3/lib/python3.6/site-packages/datasette/inspect.py\", line 79, in inspect_tables\r\n \"PRAGMA table_info({});\".format(escape_sqlite(table))\r\nsqlite3.OperationalError: no such module: VirtualSpatialIndex\r\n``` \r\n\r\nIt would be nice to trap this and return a message saying something like:\r\n\r\n```\r\nIt looks like you're trying to load a SpatiaLite database? Make sure you load in the SpatiaLite extension when starting datasette.\r\n\r\nRead more: https://datasette.readthedocs.io/en/latest/spatialite.html\r\n```\r\n\r\n", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/331/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 328155946, "node_id": "MDU6SXNzdWUzMjgxNTU5NDY=", "number": 301, "title": "--spatialite option for \"datasette publish heroku\"", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2018-05-31T14:13:09Z", "updated_at": "2022-01-20T21:28:50Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "Split off from #243. Need to figure out how to install and configure SpatiaLite on Heroku.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/301/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 838382890, "node_id": "MDU6SXNzdWU4MzgzODI4OTA=", "number": 1273, "title": "Refresh SpatiaLite documentation", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2021-03-23T06:05:55Z", "updated_at": "2022-01-20T21:28:50Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "https://docs.datasette.io/en/0.55/spatialite.html was written before I had tools like [geojson-to-sqlite](https://datasette.io/tools/geojson-to-sqlite) and [shapefile-to-sqlite](https://datasette.io/tools/shapefile-to-sqlite).", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1273/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 849975810, "node_id": "MDU6SXNzdWU4NDk5NzU4MTA=", "number": 1292, "title": "Research ctypes.util.find_library('spatialite')", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2021-04-04T22:36:59Z", "updated_at": "2022-01-20T21:28:50Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "Spotted this in the Django SpatiaLite backend: https://github.com/django/django/blob/8f6a7a0e9e7c5404af6520ae606927e32415eb00/django/contrib/gis/db/backends/spatialite/base.py#L24-L36\r\n\r\n```python\r\nctypes.util.find_library('spatialite')\r\n```", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1292/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1104691662, "node_id": "I_kwDOBm6k_c5B2EHO", "number": 1600, "title": "plugins --all example should use cog", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-01-15T11:47:49Z", "updated_at": "2022-01-20T05:06:21Z", "closed_at": "2022-01-20T05:04:16Z", "author_association": "OWNER", "pull_request": null, "body": "The example output for `datasette plugins --all`on this page has got out of date: https://docs.datasette.io/en/stable/plugins.html#seeing-what-plugins-are-installed", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1600/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1108846067, "node_id": "I_kwDOBm6k_c5CF6Xz", "number": 1606, "title": "Tests failing against Python 3.6", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2022-01-20T04:22:44Z", "updated_at": "2022-01-20T04:36:42Z", "closed_at": "2022-01-20T04:36:42Z", "author_association": "OWNER", "pull_request": null, "body": "https://github.com/simonw/datasette/runs/4877484366\r\n\r\n```\r\nE File \"/opt/hostedtoolcache/Python/3.6.15/x64/lib/python3.6/site-packages/uvicorn/server.py\", line 67, in run\r\nE return asyncio.run(self.serve(sockets=sockets))\r\nE AttributeError: module 'asyncio' has no attribute 'run'\r\n```\r\nI think this may mean `uvicorn` has dropped support for Python 3.6.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1606/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1097040427, "node_id": "I_kwDOBm6k_c5BY4Ir", "number": 1587, "title": "Add `sqlite_stat1`(-4) tables to hidden table list", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2022-01-08T21:28:20Z", "updated_at": "2022-01-20T04:12:59Z", "closed_at": "2022-01-20T04:12:59Z", "author_association": "OWNER", "pull_request": null, "body": "> Running `ANALYZE` creates a new visible table called `sqlite_stat1`: https://www.sqlite.org/fileformat.html#the_sqlite_stat1_table\r\n>\r\n> This should be added to the default list of hidden tables in Datasette.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1587/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 910092577, "node_id": "MDU6SXNzdWU5MTAwOTI1Nzc=", "number": 1356, "title": "Research: syntactic sugar for using --get with SQL queries, maybe \"datasette query\"", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 10, "created_at": "2021-06-03T04:49:42Z", "updated_at": "2022-01-20T01:06:37Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "Inspired by https://github.com/simonw/sqlite-utils/issues/264 - in particular this example:\r\n```\r\ndatasette covid.db --get='/covid.yaml?sql=select * from ny_times_us_counties limit 1' \r\n- date: '2020-01-21'\r\n county: Snohomish\r\n state: Washington\r\n fips: 53061\r\n cases: 1\r\n deaths: 0\r\n```\r\nHaving to construct that URL - including potentially URL escaping the SQL query - isn't a great developer experience.\r\n\r\nImagine if you could do this instead:\r\n\r\n datasette covid.db --query \"select * from ny_times_us_counties limit 1\" --format yaml\r\n", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1356/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1108300685, "node_id": "I_kwDOBm6k_c5CD1ON", "number": 1604, "title": "Option to assign a domain/subdomain using `datasette publish cloudrun`", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-01-19T16:21:17Z", "updated_at": "2022-01-19T16:23:54Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "Looks like this API should be able to do that: https://twitter.com/steren/status/1483835859191304192 - https://cloud.google.com/run/docs/reference/rest/v1/namespaces.domainmappings/create", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1604/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1107557831, "node_id": "I_kwDOCGYnMM5CA_3H", "number": 386, "title": "Better \"contributing\" documentation", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2022-01-19T02:11:48Z", "updated_at": "2022-01-19T02:15:21Z", "closed_at": "2022-01-19T02:15:21Z", "author_association": "OWNER", "pull_request": null, "body": "This page jumps straight into running the tests: https://sqlite-utils.datasette.io/en/latest/contributing.html\r\n\r\nIt should add a little more about expected collaboration styles - opening an issue before filing a pull request - and probably link to https://simonwillison.net/2022/Jan/12/how-i-build-a-feature/", "repo": {"value": 140912432, "label": "sqlite-utils"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/sqlite-utils/issues/386/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1100015398, "node_id": "I_kwDOBm6k_c5BkOcm", "number": 1591, "title": "Maybe let plugins define custom serve options?", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 7, "created_at": "2022-01-12T08:18:47Z", "updated_at": "2022-01-15T11:56:59Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "https://twitter.com/psychemedia/status/1481171650934714370\r\n\r\n> can extensions be passed their own cli args? eg `--ext-tiddlywiki-dbname tiddlywiki2.sqlite` ?\r\n\r\nI've thought something like this might be useful for other plugins in the past, too.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1591/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1102966378, "node_id": "I_kwDOBm6k_c5Bve5q", "number": 1599, "title": "Add architecture documentation", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2022-01-14T04:55:38Z", "updated_at": "2022-01-14T04:56:03Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "Inspired by https://matklad.github.io/2021/02/06/ARCHITECTURE.md.html\r\n\r\nGood example: https://github.com/rust-analyzer/rust-analyzer/blob/d7c99931d05e3723d878bea5dc26766791fa4e69/docs/dev/architecture.md", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1599/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1083669410, "node_id": "I_kwDOBm6k_c5Al3ui", "number": 1566, "title": "Release Datasette 0.60", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 6, "created_at": "2021-12-17T22:58:12Z", "updated_at": "2022-01-14T01:59:55Z", "closed_at": "2022-01-14T01:59:55Z", "author_association": "OWNER", "pull_request": null, "body": "Using this as a tracking issue. I'm hoping to get the bulk of the JSON redesign work from the refactor in #1554 in for this release.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1566/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1102484126, "node_id": "I_kwDOBm6k_c5BtpKe", "number": 1595, "title": "Release notes for 0.60", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 4, "created_at": "2022-01-13T22:23:14Z", "updated_at": "2022-01-14T01:37:39Z", "closed_at": "2022-01-14T01:37:39Z", "author_association": "OWNER", "pull_request": null, "body": null, "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1595/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1099723916, "node_id": "I_kwDOBm6k_c5BjHSM", "number": 1590, "title": "Table+query JSON and CSV links broken when using `base_url` setting", "user": {"value": 1001306, "label": "eelkevdbos"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 11, "created_at": "2022-01-11T23:46:39Z", "updated_at": "2022-01-14T01:16:34Z", "closed_at": "2022-01-14T01:16:08Z", "author_association": "NONE", "pull_request": null, "body": "Datasette appends the prefix found in the `base_url` setting twice if a `base_url` is set.\r\n\r\nIn the follow asgi example, I'm hosting a custom Datasette instance:\r\n\r\n```python\r\n# asgi.py\r\nimport pathlib\r\nfrom asgi_cors import asgi_cors\r\nfrom channels.routing import URLRouter\r\nfrom django.urls import re_path\r\nfrom datasette.app import Datasette\r\n\r\ndatasette_ = Datasette(\r\n files=[],\r\n settings={\r\n \"base_url\": \"/datasettes/\",\r\n \"plugins\": {}\r\n },\r\n config_dir=pathlib.Path('.'),\r\n)\r\napplication = URLRouter([\r\n re_path(r\"^datasettes/.*\", asgi_cors(datasette_.app(), allow_all=True)),\r\n])\r\n```\r\n\r\nRunning it with:\r\n```shell\r\n$ daphne -p 8002 asgi:application\r\n```\r\n\r\nUsing a simple query on the `_memory` table: \r\n```sql\r\nselect sqlite_version()\r\n```\r\n\r\nhttp://localhost:8002/datasettes/_memory?sql=select+sqlite_version%28%29\r\n\r\nIt renders the following upon inspection:\r\n![image](https://user-images.githubusercontent.com/1001306/149038851-aa842950-126a-467c-9a86-fae13bce6221.png)\r\n\r\nI am using datasette version `0.59.4`", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1590/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1059555791, "node_id": "I_kwDOBm6k_c4_J4nP", "number": 1527, "title": "Columns starting with an underscore behave poorly in filters", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 7, "created_at": "2021-11-22T01:01:36Z", "updated_at": "2022-01-14T00:57:08Z", "closed_at": "2022-01-14T00:57:08Z", "author_association": "OWNER", "pull_request": null, "body": "Similar bug to #1525 (and #1506 before it). Start on https://latest.datasette.io/fixtures/facetable?_facet=_neighborhood - then select a neighborhood - then try to remove that filter using the little \"x\" and submitting the form again.\r\n\r\n![filter-bug](https://user-images.githubusercontent.com/9599/142786754-31d265a2-944d-4ea2-af6f-305d445a2ccb.gif)\r\n", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1527/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1102637351, "node_id": "I_kwDOBm6k_c5BuOkn", "number": 1598, "title": "Replace update-docs-help.py script with cog", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-01-14T00:33:27Z", "updated_at": "2022-01-14T00:47:57Z", "closed_at": "2022-01-14T00:47:57Z", "author_association": "OWNER", "pull_request": null, "body": "I introduced `cog` in #1594 - I can use this to replace the older `update-docs-help.py` mechanism:\r\n\r\nhttps://github.com/simonw/datasette/blob/76d66d5b2bf10249c0beaac0999b93ac8d757f48/tests/test_docs.py#L36-L53", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1598/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1102612922, "node_id": "I_kwDOBm6k_c5BuIm6", "number": 1597, "title": "\"datasette inspect\" has no help summary", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-01-14T00:02:16Z", "updated_at": "2022-01-14T00:07:36Z", "closed_at": "2022-01-14T00:07:36Z", "author_association": "OWNER", "pull_request": null, "body": "Made obvious by the new CLI reference page added in #1594. https://docs.datasette.io/en/latest/cli-reference.html#datasette-inspect-help\r\n```\r\nCommands:\r\n serve* Serve up specified SQLite database files with a web UI\r\n inspect\r\n install Install Python packages - e.g.\r\n```\r\n```\r\nUsage: datasette inspect [OPTIONS] [FILES]...\r\n\r\nOptions:\r\n --inspect-file TEXT\r\n --load-extension TEXT Path to a SQLite extension to load\r\n --help Show this message and exit.\r\n```", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1597/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1102568047, "node_id": "I_kwDOBm6k_c5Bt9pv", "number": 1596, "title": "Documentation page warning of changes coming in 1.0", "user": {"value": 9599, "label": "simonw"}, "state": "open", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2022-01-13T23:26:04Z", "updated_at": "2022-01-13T23:26:04Z", "closed_at": null, "author_association": "OWNER", "pull_request": null, "body": "I should start this relatively soon.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1596/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": null} {"id": 1082746149, "node_id": "I_kwDOBm6k_c5AiWUl", "number": 1560, "title": "Table page title has \"where where\" in it", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 0, "created_at": "2021-12-17T00:05:48Z", "updated_at": "2022-01-13T22:28:35Z", "closed_at": "2022-01-13T22:20:15Z", "author_association": "OWNER", "pull_request": null, "body": "Just noticed this while working on #1518.\r\n\r\n```\r\n% curl -s 'https://latest.datasette.io/fixtures/facetable?_sort=pk&on_earth__exact=1' | grep -C 1 ''\r\n<head>\r\n <title>fixtures: facetable: 14 rows\r\n where where on_earth = 1 sorted by pk\r\n```", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1560/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 991467558, "node_id": "MDU6SXNzdWU5OTE0Njc1NTg=", "number": 1466, "title": "Add Datasette Desktop to installation documentation", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 2, "created_at": "2021-09-08T19:41:27Z", "updated_at": "2022-01-13T22:28:28Z", "closed_at": "2022-01-13T21:55:18Z", "author_association": "OWNER", "pull_request": null, "body": "See https://datasette.io/desktop and https://simonwillison.net/2021/Sep/8/datasette-desktop/", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1466/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1102359726, "node_id": "I_kwDOBm6k_c5BtKyu", "number": 1594, "title": "Add a CLI reference page to the docs, inspired by sqlite-utils", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 3, "created_at": "2022-01-13T20:55:08Z", "updated_at": "2022-01-13T22:28:22Z", "closed_at": "2022-01-13T21:38:48Z", "author_association": "OWNER", "pull_request": null, "body": "Thought of this while posting this comment: https://github.com/simonw/datasette/issues/1591#issuecomment-1012506595\r\n\r\nI added https://sqlite-utils.datasette.io/en/stable/cli-reference.html to `sqlite-utils` in https://github.com/simonw/sqlite-utils/issues/383 and I _really_ like it - it's a page showing the `--help` output of every CLI command for that tool.\r\n\r\nIt's maintained using `cog`. One of the benefits is that I get a free commit history of changes to `--help` at https://github.com/simonw/sqlite-utils/commits/main/docs/cli-reference.rst", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1594/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1097101917, "node_id": "I_kwDOBm6k_c5BZHJd", "number": 1588, "title": "`explain query plan select` is too strict about whitespace", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 3, "created_at": "2022-01-09T04:22:42Z", "updated_at": "2022-01-13T22:28:19Z", "closed_at": "2022-01-13T20:35:05Z", "author_association": "OWNER", "pull_request": null, "body": "`explain query plan select * from facetable` is allowed: https://latest.datasette.io/fixtures?sql=explain+query+plan+select+*+from+facetable\r\n\r\nBut... `explain query plan select * from facetable` (with two spaces before the `select`) returns a \"Statement must be a SELECT\" error: https://latest.datasette.io/fixtures?sql=explain+query+plan++select+*+from+facetable", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1588/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"}