home / github

Menu
  • Search all tables
  • GraphQL API

issue_comments

Table actions
  • GraphQL API for issue_comments

43 rows where "updated_at" is on date 2022-10-27 sorted by updated_at descending

✖
✖

✎ View and edit SQL

This data as json, CSV (advanced)

issue 15

  • API to insert a single record into an existing table 11
  • SQL query field can't begin by a comment 6
  • API for bulk inserting records into a table 6
  • Design URLs for the write API 5
  • Release 0.63 3
  • `datasette create-token` ability to create tokens with a reduced set of permissions 2
  • don't use immutable=1, only mode=ro 2
  • Rename master branch to main 1
  • Adjust height of textarea for no JS case 1
  • use inspect data for hash and file size 1
  • Make hash and size a lazy property 1
  • Bump black from 22.8.0 to 22.10.0 1
  • Write API in Datasette core 1
  • Create a new table from one or more records, `sqlite-utils` style 1
  • Stop syncing main to master 1

user 4

  • simonw 39
  • CharlesNepote 2
  • fgregg 1
  • codecov[bot] 1

author_association 3

  • OWNER 39
  • NONE 3
  • CONTRIBUTOR 1
id html_url issue_url node_id user created_at updated_at ▲ author_association body reactions issue performed_via_github_app
1294238862 https://github.com/simonw/datasette/pull/1870#issuecomment-1294238862 https://api.github.com/repos/simonw/datasette/issues/1870 IC_kwDOBm6k_c5NJISO codecov[bot] 22429695 2022-10-27T23:44:25Z 2022-10-27T23:44:25Z NONE

Codecov Report

Base: 92.55% // Head: 92.55% // No change to project coverage :thumbsup:

Coverage data is based on head (4faa4fd) compared to base (bf00b0b). Patch has no changes to coverable lines.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #1870 +/- ## ======================================= Coverage 92.55% 92.55% ======================================= Files 35 35 Lines 4432 4432 ======================================= Hits 4102 4102 Misses 330 330 ``` | [Impacted Files](https://codecov.io/gh/simonw/datasette/pull/1870?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | | |---|---|---| | [datasette/app.py](https://codecov.io/gh/simonw/datasette/pull/1870/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2FwcC5weQ==) | `94.30% <ø> (ø)` | | Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)

:umbrella: View full report at Codecov.
:loudspeaker: Do you have feedback about the report comment? Let us know in this issue.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
don't use immutable=1, only mode=ro 1426379903  
1294237783 https://github.com/simonw/datasette/pull/1870#issuecomment-1294237783 https://api.github.com/repos/simonw/datasette/issues/1870 IC_kwDOBm6k_c5NJIBX fgregg 536941 2022-10-27T23:42:18Z 2022-10-27T23:42:18Z CONTRIBUTOR

Relevant sqlite forum thread: https://www.sqlite.org/forum/forumpost/02f7bda329f41e30451472421cf9ce7f715b768ce3db02797db1768e47950d48

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
don't use immutable=1, only mode=ro 1426379903  
1289712350 https://github.com/simonw/datasette/issues/1851#issuecomment-1289712350 https://api.github.com/repos/simonw/datasette/issues/1851 IC_kwDOBm6k_c5M33Le simonw 9599 2022-10-24T22:28:39Z 2022-10-27T23:18:48Z OWNER

API design: (**UPDATE: this was later changed to POST /db/table/-/insert)

POST /db/table Authorization: Bearer xxx Content-Type: application/json { "row": { "id": 1, "name": "New record" } } Returns: 201 Created { "row": { "id": 1, "name": "New record" } } You can omit optional fields in the input, including the ID field. The returned object will always include all fields - and will even include rowid if your object doesn't have a primary key of its own.

I decided to use "row" as the key in both request and response, to preserve space for other future keys - one that tells you that the table has been created, for example.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API to insert a single record into an existing table 1421544654  
1294181485 https://github.com/simonw/datasette/issues/1869#issuecomment-1294181485 https://api.github.com/repos/simonw/datasette/issues/1869 IC_kwDOBm6k_c5NI6Rt simonw 9599 2022-10-27T22:24:37Z 2022-10-27T22:24:37Z OWNER

https://docs.datasette.io/en/stable/changelog.html#v0-63

Annotated release notes: https://simonwillison.net/2022/Oct/27/datasette-0-63/

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Release 0.63 1426253476  
1294116493 https://github.com/simonw/datasette/issues/1786#issuecomment-1294116493 https://api.github.com/repos/simonw/datasette/issues/1786 IC_kwDOBm6k_c5NIqaN simonw 9599 2022-10-27T21:50:12Z 2022-10-27T21:50:12Z OWNER

Demo in Datasette Lite: https://lite.datasette.io/#/fixtures?sql=select%0A++pk1%2C%0A++pk2%2C%0A++content%2C%0A++sortable%2C%0A++sortable_with_nulls%2C%0A++sortable_with_nulls_2%2C%0A++text%0Afrom%0A++sortable%0Aorder+by%0A++pk1%2C%0A++pk2%0Alimit%0A++101

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Adjust height of textarea for no JS case 1342430983  
1294105558 https://github.com/simonw/datasette/issues/1869#issuecomment-1294105558 https://api.github.com/repos/simonw/datasette/issues/1869 IC_kwDOBm6k_c5NInvW simonw 9599 2022-10-27T21:44:13Z 2022-10-27T21:44:13Z OWNER

I'm going to do annotated release notes for this one.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Release 0.63 1426253476  
1294056552 https://github.com/simonw/datasette/issues/1869#issuecomment-1294056552 https://api.github.com/repos/simonw/datasette/issues/1869 IC_kwDOBm6k_c5NIbxo simonw 9599 2022-10-27T21:00:02Z 2022-10-27T21:02:25Z OWNER

Those release notes as markdown:

Features

  • Now tested against Python 3.11. Docker containers used by datasette publish and datasette package both now use that version of Python. (#1853)
  • --load-extension option now supports entrypoints. Thanks, Alex Garcia. (#1789)
  • Facet size can now be set per-table with the new facet_size table metadata option. (#1804)
  • The truncate_cells_html setting now also affects long URLs in columns. (#1805)
  • The non-JavaScript SQL editor textarea now increases height to fit the SQL query. (#1786)
  • Facets are now displayed with better line-breaks in long values. Thanks, Daniel Rech. (#1794)
  • The settings.json file used in Configuration directory mode is now validated on startup. (#1816)
  • SQL queries can now include leading SQL comments, using /* ... */ or -- ... syntax. Thanks, Charles Nepote. (#1860)
  • SQL query is now re-displayed when terminated with a time limit error. (#1819)
  • The inspect data mechanism is now used to speed up server startup - thanks, Forest Gregg. (#1834)
  • In Configuration directory mode databases with filenames ending in .sqlite or .sqlite3 are now automatically added to the Datasette instance. (#1646)
  • Breadcrumb navigation display now respects the current user's permissions. (#1831)

Plugin hooks and internals

  • The prepare_jinja2_environment(env, datasette) plugin hook now accepts an optional datasette argument. Hook implementations can also now return an async function which will be awaited automatically. (#1809)
  • Database(is_mutable=) now defaults to True. (#1808)
  • The datasette.check_visibility() method now accepts an optional permissions= list, allowing it to take multiple permissions into account at once when deciding if something should be shown as public or private. This has been used to correctly display padlock icons in more places in the Datasette interface. (#1829)
  • Datasette no longer enforces upper bounds on its dependencies. (#1800)

Documentation

  • New tutorial: Cleaning data with sqlite-utils and Datasette.
  • Screenshots in the documentation are now maintained using shot-scraper, as described in Automating screenshots for the Datasette documentation using shot-scraper. (#1844)
  • More detailed command descriptions on the CLI reference page. (#1787)
  • New documentation on Running Datasette using OpenRC - thanks, Adam Simpson. (#1825)
{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Release 0.63 1426253476  
1294049178 https://github.com/simonw/datasette/pull/1835#issuecomment-1294049178 https://api.github.com/repos/simonw/datasette/issues/1835 IC_kwDOBm6k_c5NIZ-a simonw 9599 2022-10-27T20:51:30Z 2022-10-27T20:51:30Z OWNER

See also: - https://github.com/simonw/datasette/pull/1837

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
use inspect data for hash and file size 1400121355  
1294048849 https://github.com/simonw/datasette/pull/1837#issuecomment-1294048849 https://api.github.com/repos/simonw/datasette/issues/1837 IC_kwDOBm6k_c5NIZ5R simonw 9599 2022-10-27T20:51:08Z 2022-10-27T20:51:08Z OWNER

Yeah this is better, thanks!

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Make hash and size a lazy property 1400431789  
1294034011 https://github.com/simonw/datasette/pull/1839#issuecomment-1294034011 https://api.github.com/repos/simonw/datasette/issues/1839 IC_kwDOBm6k_c5NIWRb simonw 9599 2022-10-27T20:34:37Z 2022-10-27T20:34:37Z OWNER

@dependabot rebase

{
    "total_count": 1,
    "+1": 1,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Bump black from 22.8.0 to 22.10.0 1401155623  
1294012583 https://github.com/simonw/datasette/issues/1851#issuecomment-1294012583 https://api.github.com/repos/simonw/datasette/issues/1851 IC_kwDOBm6k_c5NIRCn simonw 9599 2022-10-27T20:11:22Z 2022-10-27T20:11:22Z OWNER

And the response to "inserted": [{...}] - it will be the same for bulk inserts.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API to insert a single record into an existing table 1421544654  
1294012084 https://github.com/simonw/datasette/issues/1851#issuecomment-1294012084 https://api.github.com/repos/simonw/datasette/issues/1851 IC_kwDOBm6k_c5NIQ60 simonw 9599 2022-10-27T20:10:47Z 2022-10-27T20:10:47Z OWNER

I'm going to change the incoming JSON back to {"row": {...}} - no need to POST {"insert": ...} to something with /-/insert in the URL already.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API to insert a single record into an existing table 1421544654  
1294009354 https://github.com/simonw/datasette/issues/1851#issuecomment-1294009354 https://api.github.com/repos/simonw/datasette/issues/1851 IC_kwDOBm6k_c5NIQQK simonw 9599 2022-10-27T20:07:42Z 2022-10-27T20:07:42Z OWNER

Need to implement the new URL design from: - #1868

This is now going to be /db/table/-/insert - and it will eventually handle bulk inserts as well as single inserts.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API to insert a single record into an existing table 1421544654  
1294008733 https://github.com/simonw/datasette/issues/1868#issuecomment-1294008733 https://api.github.com/repos/simonw/datasette/issues/1868 IC_kwDOBm6k_c5NIQGd simonw 9599 2022-10-27T20:07:01Z 2022-10-27T20:07:01Z OWNER

I'm happy with this /db/table/-/action design for the moment. Will review it once I've built it to see if I still like it!

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Design URLs for the write API 1426195437  
1294008282 https://github.com/simonw/datasette/issues/1868#issuecomment-1294008282 https://api.github.com/repos/simonw/datasette/issues/1868 IC_kwDOBm6k_c5NIP_a simonw 9599 2022-10-27T20:06:34Z 2022-10-27T20:06:34Z OWNER

I'm going to stick with one /-/insert endpoint which handles both single row inserts AND multiple row inserts I think - partly because I don't want to build both /-/upsert and /-/upsert-many, I'd rather just have /-/upsert.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Design URLs for the write API 1426195437  
1294007024 https://github.com/simonw/datasette/issues/1868#issuecomment-1294007024 https://api.github.com/repos/simonw/datasette/issues/1868 IC_kwDOBm6k_c5NIPrw simonw 9599 2022-10-27T20:05:44Z 2022-10-27T20:05:52Z OWNER

So given this scheme, the URL design would look like this:

  • POST /db/table/-/insert - insert a single row
  • POST /db/table/-/insert-many - insert multiple rows (might just keep that on /-/insert with a JSON array rather than object though)
  • POST /db/table/-/drop - drop a table
  • POST /db/table/-/alter - alter a table
  • POST /db/table/-/upsert - upsert, https://sqlite-utils.datasette.io/en/stable/python-api.html#upserting-data
  • POST /db/table/-/create - could be an endpoint for explicitly creating a table, or should that live at /db/-/create instead?

And for rows (pks here since compound primary keys are supported):

  • POST /db/table/pks/-/update - update row
  • POST /db/table/pks/-/delete - delete row
{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Design URLs for the write API 1426195437  
1294004308 https://github.com/simonw/datasette/issues/1868#issuecomment-1294004308 https://api.github.com/repos/simonw/datasette/issues/1868 IC_kwDOBm6k_c5NIPBU simonw 9599 2022-10-27T20:03:08Z 2022-10-27T20:03:08Z OWNER

The other option here would be to lean into custom HTTP verbs like DELETE and PATCH. I'm not sold on those: they've never given me any convincing wins over just using POST for the many times I've encountered them in my career to date.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Design URLs for the write API 1426195437  
1294003701 https://github.com/simonw/datasette/issues/1868#issuecomment-1294003701 https://api.github.com/repos/simonw/datasette/issues/1868 IC_kwDOBm6k_c5NIO31 simonw 9599 2022-10-27T20:02:26Z 2022-10-27T20:02:26Z OWNER

The problem with the above design is that I want to support a bunch of different actions that can be taken against a table: - insert a single row - insert multiple rows - bulk update rows - rename table - alter table - drop table

I could have ALL of those be a POST /db/table with different JSON root keys ({"drop": true} for example, but this raises two problems:

  1. Server logs that only show POST /db/table will be less useful, they won't reveal what action was performed
  2. What happens if you send {"insert": {"title": "New record"}, "drop": true}? Does that return an error, or does it perform both of those actions?

This is already slightly confusing in that POST /db/name-of-query is the existing API for executing a writable canned query: https://docs.datasette.io/en/stable/sql_queries.html#json-api-for-writable-canned-queries

So I'm ready to consider other design options.

Initial thoughts on possible designs (for the single row insert case, but could be expanded to cover other verbs):

  • POST /db/table?action=insert
  • POST /db/table?nsert
  • POST /db/table/-/insert

I quite like that third one: it feels consistent with the existing /-/actor etc pages that Datasette serves already.

There's one slight confusion here in that it overlaps with the URL for a row with a primary key of "-" - which is currently at /db/table/- - but that might be OK.

Especially if I say that child pages of rows must theselves use the /-/ pattern. So to update or delet a row you would use:

  • POST /db/table/row/-/update
  • POST /db/table/row/-/delete

So a row with primary key - would end up as /db/table/row/-/-/update - which I think is OK.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Design URLs for the write API 1426195437  
1293996735 https://github.com/simonw/datasette/issues/1851#issuecomment-1293996735 https://api.github.com/repos/simonw/datasette/issues/1851 IC_kwDOBm6k_c5NINK_ simonw 9599 2022-10-27T19:54:53Z 2022-10-27T19:54:53Z OWNER

Updated docs: https://docs.datasette.io/en/1.0-dev/json_api.html#inserting-a-single-row

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API to insert a single record into an existing table 1421544654  
1292997608 https://github.com/simonw/datasette/issues/1851#issuecomment-1292997608 https://api.github.com/repos/simonw/datasette/issues/1851 IC_kwDOBm6k_c5NEZPo simonw 9599 2022-10-27T04:54:53Z 2022-10-27T19:05:50Z OWNER

I'm going to change the design of this to: { "insert": { "title" :"..." } } Renaming "row" to "insert".

This will be consistent with adding "drop": true for dropping a table, and maybe other verbs like for modifying the schema.

The API response will look like this:

json { "inserted_row": { "id": 1, "title": "..." } }

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API to insert a single record into an existing table 1421544654  
1293939737 https://github.com/simonw/datasette/issues/1860#issuecomment-1293939737 https://api.github.com/repos/simonw/datasette/issues/1860 IC_kwDOBm6k_c5NH_QZ simonw 9599 2022-10-27T18:57:37Z 2022-10-27T18:57:37Z OWNER

The new code is now live at https://latest.datasette.io/fixtures

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
SQL query field can't begin by a comment 1424378012  
1293928738 https://github.com/simonw/datasette/issues/1860#issuecomment-1293928738 https://api.github.com/repos/simonw/datasette/issues/1860 IC_kwDOBm6k_c5NH8ki simonw 9599 2022-10-27T18:46:31Z 2022-10-27T18:46:31Z OWNER

I think mine has a better pattern for handling /* ... anything in here that isn't */ ... */

{
    "total_count": 1,
    "+1": 1,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
SQL query field can't begin by a comment 1424378012  
1293928230 https://github.com/simonw/datasette/issues/1860#issuecomment-1293928230 https://api.github.com/repos/simonw/datasette/issues/1860 IC_kwDOBm6k_c5NH8cm simonw 9599 2022-10-27T18:46:03Z 2022-10-27T18:46:03Z OWNER

Here's yours on Debuggex: https://www.debuggex.com/r/HjdJryTy9ezGsuWK

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
SQL query field can't begin by a comment 1424378012  
1293926417 https://github.com/simonw/datasette/issues/1860#issuecomment-1293926417 https://api.github.com/repos/simonw/datasette/issues/1860 IC_kwDOBm6k_c5NH8AR simonw 9599 2022-10-27T18:44:20Z 2022-10-27T18:45:21Z OWNER

Hah, I just came up with this one - we were clearly working on this at the same time!

^\s*((?:\-\-.*?\n\s*)|(?:\/\*((?!\*\/)[\s\S])*\*\/)\s*)*\s*select\b

https://www.debuggex.com/r/Rbw-UWD9PdOU2GyO

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
SQL query field can't begin by a comment 1424378012  
1293912781 https://github.com/simonw/datasette/issues/1860#issuecomment-1293912781 https://api.github.com/repos/simonw/datasette/issues/1860 IC_kwDOBm6k_c5NH4rN CharlesNepote 562352 2022-10-27T18:31:15Z 2022-10-27T18:31:15Z NONE

Here is my suggestion:

^\s*((?:\-\-.*?\n\s*)|(?:/\*.*?(?=\*/)\*/\s*))*select\b

See the following test: https://regex101.com/r/Doeqqa/1

And here I played all your tests: https://regexr.com/713ir

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
SQL query field can't begin by a comment 1424378012  
1293893789 https://github.com/simonw/datasette/issues/1866#issuecomment-1293893789 https://api.github.com/repos/simonw/datasette/issues/1866 IC_kwDOBm6k_c5NH0Cd simonw 9599 2022-10-27T18:13:00Z 2022-10-27T18:13:00Z OWNER

If people care about that kind of thing they could always push all of their inserts to a table called _tablename and then atomically rename that once they've uploaded all of the data (assuming I provide an atomic-rename-this-table mechanism).

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API for bulk inserting records into a table 1426001541  
1293892818 https://github.com/simonw/datasette/issues/1866#issuecomment-1293892818 https://api.github.com/repos/simonw/datasette/issues/1866 IC_kwDOBm6k_c5NHzzS simonw 9599 2022-10-27T18:12:02Z 2022-10-27T18:12:02Z OWNER

There's one catch with batched inserts: if your CLI tool fails half way through you could end up with a partially populated table - since a bunch of batches will have succeeded first.

I think that's OK. In the future I may want to come up with a way to run multiple batches of inserts inside a single transaction, but I can ignore that for the first release of this feature.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API for bulk inserting records into a table 1426001541  
1293891876 https://github.com/simonw/datasette/issues/1866#issuecomment-1293891876 https://api.github.com/repos/simonw/datasette/issues/1866 IC_kwDOBm6k_c5NHzkk simonw 9599 2022-10-27T18:11:05Z 2022-10-27T18:11:05Z OWNER

Likewise for newline-delimited JSON. While it's tempting to want to accept that as an ingest format (because it's nice to generate and stream) I think it's better to have a client application that can turn a stream of newline-delimited JSON into batched JSON inserts.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API for bulk inserting records into a table 1426001541  
1293891191 https://github.com/simonw/datasette/issues/1866#issuecomment-1293891191 https://api.github.com/repos/simonw/datasette/issues/1866 IC_kwDOBm6k_c5NHzZ3 simonw 9599 2022-10-27T18:10:22Z 2022-10-27T18:10:22Z OWNER

So for the moment I'm just going to concentrate on the JSON API. I can consider CSV variants later on, or as plugins, or both.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API for bulk inserting records into a table 1426001541  
1293890684 https://github.com/simonw/datasette/issues/1866#issuecomment-1293890684 https://api.github.com/repos/simonw/datasette/issues/1866 IC_kwDOBm6k_c5NHzR8 simonw 9599 2022-10-27T18:09:52Z 2022-10-27T18:09:52Z OWNER

Should this API accept CSV/TSV etc in addition to JSON?

I'm torn on this one. My initial instinct is that it should not - and there should instead be a Datasette client library / CLI tool you can use that knows how to turn CSV into batches of JSON calls for when you want to upload a CSV file.

I don't think the usability of curl https://datasette/db/table -F 'data=@path/to/file.csv' -H 'Authentication: Bearer xxx' is particularly great compared to something likedatasette client insert https://datasette/ db table file.csv --csv (where the command version could store API tokens for you too).

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API for bulk inserting records into a table 1426001541  
1293887808 https://github.com/simonw/datasette/issues/1866#issuecomment-1293887808 https://api.github.com/repos/simonw/datasette/issues/1866 IC_kwDOBm6k_c5NHylA simonw 9599 2022-10-27T18:07:02Z 2022-10-27T18:07:02Z OWNER

Error handling is really important here.

What should happen if you submit 100 records and one of them has some kind of validation error? How should that error be reported back to you?

I'm inclined to say that it defaults to all-or-nothing in a transaction - but there should be a "continue_on_error": true option (or similar) which causes it to insert the ones that are valid while reporting back the ones that are invalid.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API for bulk inserting records into a table 1426001541  
1293863145 https://github.com/simonw/datasette/issues/1860#issuecomment-1293863145 https://api.github.com/repos/simonw/datasette/issues/1860 IC_kwDOBm6k_c5NHsjp CharlesNepote 562352 2022-10-27T17:43:37Z 2022-10-27T17:43:37Z NONE

Sorry I forgot the -- comments like that.

I'm afraid there is an issue in your regexp, see: https://regex101.com/r/pyubJf/1

I guess I can fix it.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
SQL query field can't begin by a comment 1424378012  
1293857306 https://github.com/simonw/datasette/issues/1862#issuecomment-1293857306 https://api.github.com/repos/simonw/datasette/issues/1862 IC_kwDOBm6k_c5NHrIa simonw 9599 2022-10-27T17:38:17Z 2022-10-27T17:38:17Z OWNER

Strongly related to: - #1866

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Create a new table from one or more records, `sqlite-utils` style 1425011030  
1293568194 https://github.com/simonw/datasette/issues/1865#issuecomment-1293568194 https://api.github.com/repos/simonw/datasette/issues/1865 IC_kwDOBm6k_c5NGkjC simonw 9599 2022-10-27T13:58:26Z 2022-10-27T13:58:26Z OWNER

Here's the issue where I started doing this: - #849

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Stop syncing main to master 1425682079  
649908756 https://github.com/simonw/datasette/issues/849#issuecomment-649908756 https://api.github.com/repos/simonw/datasette/issues/849 MDEyOklzc3VlQ29tbWVudDY0OTkwODc1Ng== simonw 9599 2020-06-26T02:09:09Z 2022-10-27T13:57:08Z OWNER

I mentioned this issue here: https://simonwillison.net/2020/Jun/26/weeknotes-plugins-sqlite-generate/

Repositories created by following the README in https://github.com/simonw/datasette-template and https://github.com/simonw/click-app have a main branch instead of master so I have a few examples live now. https://github.com/simonw/datasette-saved-queries is one example.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Rename master branch to main 639072811  
1292999579 https://github.com/simonw/datasette/issues/1851#issuecomment-1292999579 https://api.github.com/repos/simonw/datasette/issues/1851 IC_kwDOBm6k_c5NEZub simonw 9599 2022-10-27T04:59:06Z 2022-10-27T04:59:12Z OWNER

I should probably refactor this to use sqlite-utils, since I'm going to want to use that later for the feature that automatically creates tables.

Might make it easier to solve the rowid issues too.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API to insert a single record into an existing table 1421544654  
1292996181 https://github.com/simonw/datasette/issues/1851#issuecomment-1292996181 https://api.github.com/repos/simonw/datasette/issues/1851 IC_kwDOBm6k_c5NEY5V simonw 9599 2022-10-27T04:51:47Z 2022-10-27T04:51:47Z OWNER

Also need a test for invalid JSON (currently triggers a 500 HTML error).

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API to insert a single record into an existing table 1421544654  
1292962813 https://github.com/simonw/datasette/issues/1855#issuecomment-1292962813 https://api.github.com/repos/simonw/datasette/issues/1855 IC_kwDOBm6k_c5NEQv9 simonw 9599 2022-10-27T04:31:40Z 2022-10-27T04:31:40Z OWNER

My hunch on this is that anyone with that level of complex permissions requirements needs to be using a custom authentication plugin which includes much more concrete token rules, rather than the default signed stateless token implementation that ships with Datasette core.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089  
1292959886 https://github.com/simonw/datasette/issues/1855#issuecomment-1292959886 https://api.github.com/repos/simonw/datasette/issues/1855 IC_kwDOBm6k_c5NEQCO simonw 9599 2022-10-27T04:30:07Z 2022-10-27T04:30:07Z OWNER

Here's an interesting edge-case to consider: what if a user creates themselves a token for a specific table, then deletes that table, and waits for another user to create a table of the same name... and then uses their previously created token to write to the table that someone else created?

Not sure if this is a threat I need to actively consider, but it's worth thinking a little bit about the implications of such a thing - since there will be APIs that allow users to create tables, and there may be cases where people want to have a concept of users "owning" specific tables.

This is probably something that could be left for plugins to solve, but it still needs to be understood and potentially documented.

There may even be a world in which tracking the timestamp at which a table was created becomes useful - because that could then be baked into API tokens, such that a token created BEFORE the table was created does not grant access to that table.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089  
1292952121 https://github.com/simonw/datasette/issues/1851#issuecomment-1292952121 https://api.github.com/repos/simonw/datasette/issues/1851 IC_kwDOBm6k_c5NEOI5 simonw 9599 2022-10-27T04:24:09Z 2022-10-27T04:24:20Z OWNER

And come up with a whole bunch of tests for weird table shapes, surprising column names, different types etc.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API to insert a single record into an existing table 1421544654  
1292951833 https://github.com/simonw/datasette/issues/1851#issuecomment-1292951833 https://api.github.com/repos/simonw/datasette/issues/1851 IC_kwDOBm6k_c5NEOEZ simonw 9599 2022-10-27T04:23:40Z 2022-10-27T04:23:40Z OWNER

Also need to think about transactions - it should use them!

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API to insert a single record into an existing table 1421544654  
1292939146 https://github.com/simonw/datasette/issues/1851#issuecomment-1292939146 https://api.github.com/repos/simonw/datasette/issues/1851 IC_kwDOBm6k_c5NEK-K simonw 9599 2022-10-27T04:00:17Z 2022-10-27T04:23:15Z OWNER

Documentation for this first draft of the API: https://docs.datasette.io/en/1.0-dev/json_api.html#inserting-a-single-row

It currently returns errors as HTML - it needs to return errors as JSON. Also the errors need comprehensive test coverage.

I'm also worried about what happens if you use it on a table that doesn't use an integer primary key - need to check that. I think this code may break:

https://github.com/simonw/datasette/blob/51c436fed29205721dcf17fa31d7e7090d34ebb8/datasette/views/table.py#L155-L171

Plus will rowid tables without an explicit primary key return the rowid column? They should.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
API to insert a single record into an existing table 1421544654  
1292940011 https://github.com/simonw/datasette/issues/1850#issuecomment-1292940011 https://api.github.com/repos/simonw/datasette/issues/1850 IC_kwDOBm6k_c5NELLr simonw 9599 2022-10-27T04:01:59Z 2022-10-27T04:01:59Z OWNER

Working on that first "insert row" implementation:

  • https://github.com/simonw/datasette/issues/1851

Has made it very clear to me that I should go the whole hog and build the basic form-based interface for this as well.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Write API in Datasette core 1421529723  

Advanced export

JSON shape: default, array, newline-delimited, object

CSV options:

CREATE TABLE [issue_comments] (
   [html_url] TEXT,
   [issue_url] TEXT,
   [id] INTEGER PRIMARY KEY,
   [node_id] TEXT,
   [user] INTEGER REFERENCES [users]([id]),
   [created_at] TEXT,
   [updated_at] TEXT,
   [author_association] TEXT,
   [body] TEXT,
   [reactions] TEXT,
   [issue] INTEGER REFERENCES [issues]([id])
, [performed_via_github_app] TEXT);
CREATE INDEX [idx_issue_comments_issue]
                ON [issue_comments] ([issue]);
CREATE INDEX [idx_issue_comments_user]
                ON [issue_comments] ([user]);
Powered by Datasette · Queries took 2791.389ms · About: github-to-sqlite
  • Sort ascending
  • Sort descending
  • Facet by this
  • Hide this column
  • Show all columns
  • Show not-blank rows