home / github

Menu
  • Search all tables
  • GraphQL API

issue_comments

Table actions
  • GraphQL API for issue_comments

12 rows where issue = 1435294468 and user = 9599 sorted by updated_at descending

✖
✖
✖

✎ View and edit SQL

This data as json, CSV (advanced)

Suggested facets: created_at (date), updated_at (date)

user 1

  • simonw · 12 ✖

issue 1

  • `/db/-/create` API for creating tables · 12 ✖

author_association 1

  • OWNER 12
id html_url issue_url node_id user created_at updated_at ▲ author_association body reactions issue performed_via_github_app
1314813205 https://github.com/simonw/datasette/issues/1882#issuecomment-1314813205 https://api.github.com/repos/simonw/datasette/issues/1882 IC_kwDOBm6k_c5OXnUV simonw 9599 2022-11-15T06:00:41Z 2022-11-15T06:00:41Z OWNER

Documentation:

  • https://docs.datasette.io/en/1.0-dev/json_api.html#creating-a-table
  • https://docs.datasette.io/en/1.0-dev/json_api.html#creating-a-table-from-example-data

Wrote a TIL about how I wrote some of those tests with Copilot: https://til.simonwillison.net/gpt3/writing-test-with-copilot

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
`/db/-/create` API for creating tables 1435294468  
1312582512 https://github.com/simonw/datasette/issues/1882#issuecomment-1312582512 https://api.github.com/repos/simonw/datasette/issues/1882 IC_kwDOBm6k_c5OPGtw simonw 9599 2022-11-12T22:11:18Z 2022-11-12T22:11:18Z OWNER

I like this:

json { "ok": true, "database": "data", "table": "agai2n", "table_url": "http://127.0.0.1:8001/data/agai2n", "schema": "CREATE TABLE [agai2n] (\n [hello] INTEGER\n)" }

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
`/db/-/create` API for creating tables 1435294468  
1312581121 https://github.com/simonw/datasette/issues/1882#issuecomment-1312581121 https://api.github.com/repos/simonw/datasette/issues/1882 IC_kwDOBm6k_c5OPGYB simonw 9599 2022-11-12T22:01:32Z 2022-11-12T22:01:32Z OWNER

I'm going to change it to table in the output AND the input.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
`/db/-/create` API for creating tables 1435294468  
1312581008 https://github.com/simonw/datasette/issues/1882#issuecomment-1312581008 https://api.github.com/repos/simonw/datasette/issues/1882 IC_kwDOBm6k_c5OPGWQ simonw 9599 2022-11-12T22:00:52Z 2022-11-12T22:00:52Z OWNER

Tried out my prototype in the API explorer:

The "name" on the output is bothering me a bit - should it be table_name or table instead?

Problem is I really like name for the input, so should it be consistent to have the same name on the output here, or should I aim for consistency with other endpoints that might return table rather than the ambiguous name elsewhere?

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
`/db/-/create` API for creating tables 1435294468  
1312580348 https://github.com/simonw/datasette/issues/1882#issuecomment-1312580348 https://api.github.com/repos/simonw/datasette/issues/1882 IC_kwDOBm6k_c5OPGL8 simonw 9599 2022-11-12T21:55:54Z 2022-11-12T21:56:45Z OWNER

What should this API return?

I think the name of the table (name), the URL to that table (table_url - for consistency with how faceting API works already) and the schema of the table (schema).

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
`/db/-/create` API for creating tables 1435294468  
1312575048 https://github.com/simonw/datasette/issues/1882#issuecomment-1312575048 https://api.github.com/repos/simonw/datasette/issues/1882 IC_kwDOBm6k_c5OPE5I simonw 9599 2022-11-12T21:22:58Z 2022-11-12T21:22:58Z OWNER

Need to validate the table name. SQLite supports almost any table name - but they can't contain a newline character and cannot start with sqlite_ - according to https://stackoverflow.com/questions/3694276/what-are-valid-table-names-in-sqlite/43049720#43049720

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
`/db/-/create` API for creating tables 1435294468  
1312556044 https://github.com/simonw/datasette/issues/1882#issuecomment-1312556044 https://api.github.com/repos/simonw/datasette/issues/1882 IC_kwDOBm6k_c5OPAQM simonw 9599 2022-11-12T19:29:11Z 2022-11-12T19:29:11Z OWNER

Thought of an edge-case: with sqlite-utils one feature I really like is that I can pipe data into it without caring if the table already exists or not:

cat data.json | sqlite-utils insert my.db mytable -

How could this new API support that?

I thought about adding a "create": true option to /db/table/-/insert which creates the table if it doesn't already exist, but if I do that I'll need to start adding other options to that endpoint - to set the primary key, add foreign keys and suchlike - which would be ignored except for the cases where the table was being created from scratch.

This doesn't feel right to me - I want to keep those options here, on /db/-/create.

One idea I had was to implement it such that you can call /db/-/create multiple times for the same table, but only if you are using the "rows" option. If so, and if the rows can be safely inserted, it would let you do that.

But instead, I'm going to outsource this to the CLI tool I plan to write that feeds data into this API. I'm already planning to use that tool for CSV inserts (so the API doesn't need to accept CSV directly). I think it's a good place for other usability enhancements like "insert this, creating the table if it does not exist" as well.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
`/db/-/create` API for creating tables 1435294468  
1302818784 https://github.com/simonw/datasette/issues/1882#issuecomment-1302818784 https://api.github.com/repos/simonw/datasette/issues/1882 IC_kwDOBm6k_c5Np2_g simonw 9599 2022-11-04T00:25:18Z 2022-11-04T16:12:39Z OWNER

On that basis I think the core API design should change to this: POST /db/-/create Authorization: Bearer xxx Content-Type: application/json { "name": "my new table", "columns": [ { "name": "id", "type": "integer" }, { "name": "title", "type": "text" } ] "pk": "id" } This leaves room for a "rows": [] key at the root too. Having that as a child of "table" felt unintuitive to me, and I didn't like the way this looked either:

json { "table": { "name": "my_new_table" }, "rows": [ {"id": 1, "title": "Title"} ] } Weird to have the table name nested inside table when rows wasn't.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
`/db/-/create` API for creating tables 1435294468  
1302818153 https://github.com/simonw/datasette/issues/1882#issuecomment-1302818153 https://api.github.com/repos/simonw/datasette/issues/1882 IC_kwDOBm6k_c5Np21p simonw 9599 2022-11-04T00:23:58Z 2022-11-04T00:23:58Z OWNER

I made a decision here that this endpoint should also accept an optional "rows": [...] list which is used to automatically create the table using a schema derived from those example rows (which then get inserted):

  • https://github.com/simonw/datasette/issues/1862#issuecomment-1302817807
{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
`/db/-/create` API for creating tables 1435294468  
1302716350 https://github.com/simonw/datasette/issues/1882#issuecomment-1302716350 https://api.github.com/repos/simonw/datasette/issues/1882 IC_kwDOBm6k_c5Npd-- simonw 9599 2022-11-03T21:51:14Z 2022-11-03T22:35:54Z OWNER

Validating this JSON object is getting a tiny bit complex. I'm tempted to adopt https://pydantic-docs.helpmanual.io/ at this point.

The create_model example on https://stackoverflow.com/questions/66168517/generate-dynamic-model-using-pydantic/66168682#66168682 is particularly relevant, especially when I work on this issue:

  • 1863

```python from pydantic import create_model

d = {"strategy": {"name": "test_strat2", "periods": 10}}

Strategy = create_model("Strategy", **d["strategy"])

print(Strategy.schema_json(indent=2)) ``create_model()`: https://pydantic-docs.helpmanual.io/usage/models/#dynamic-model-creation

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
`/db/-/create` API for creating tables 1435294468  
1302721916 https://github.com/simonw/datasette/issues/1882#issuecomment-1302721916 https://api.github.com/repos/simonw/datasette/issues/1882 IC_kwDOBm6k_c5NpfV8 simonw 9599 2022-11-03T21:58:50Z 2022-11-03T21:59:17Z OWNER

Mocked up a quick HTML+JavaScript form for creating that JSON structure using some iteration against Copilot prompts: ```html

/* JSON format:
{
  "table": {
      "name": "my new table",
      "columns": [
          {
              "name": "id",
              "type": "integer"
          },
          {
              "name": "title",
              "type": "text"
          }
      ]
     "pk": "id"
  }
}

HTML form with Javascript for creating this JSON:
*/
<form id="create-table-form"> <label for="table-name">Table name</label>
<label for="table-pk">Primary key</label>
<label for="column-name">Column name</label> <label for="column-type">Column type</label> <button type="button" id="add-column">Add column</button>

Current columns:

    <button type="button" id="create-table">Create table</button> </form> <script> var form = document.getElementById('create-table-form'); var tableName = document.getElementById('table-name'); var tablePk = document.getElementById('table-pk'); var columnName = document.getElementById('column-name'); var columnType = document.getElementById('column-type'); var addColumn = document.getElementById('add-column'); var createTable = document.getElementById('create-table'); var columns = []; addColumn.addEventListener('click', () => { columns.push({ name: columnName.value, type: columnType.value }); var li = document.createElement('li'); li.textContent = columnName.value + ' (' + columnType.value + ')'; // Add a delete button to each column var deleteButton = document.createElement('button'); deleteButton.textContent = 'Delete'; deleteButton.addEventListener('click', () => { columns.splice(columns.indexOf(li), 1); li.remove(); }); li.appendChild(deleteButton); document.getElementById('columns').appendChild(li); }); createTable.addEventListener('click', () => { var table = { name: tableName.value, pk: tablePk.value, columns: columns }; console.log(JSON.stringify(table, null, 2)); }); </script>

    ```

    {
        "total_count": 0,
        "+1": 0,
        "-1": 0,
        "laugh": 0,
        "hooray": 0,
        "confused": 0,
        "heart": 0,
        "rocket": 0,
        "eyes": 0
    }
    `/db/-/create` API for creating tables 1435294468  
    1302715662 https://github.com/simonw/datasette/issues/1882#issuecomment-1302715662 https://api.github.com/repos/simonw/datasette/issues/1882 IC_kwDOBm6k_c5Npd0O simonw 9599 2022-11-03T21:50:27Z 2022-11-03T21:50:27Z OWNER

    API design for this: POST /db/-/create Authorization: Bearer xxx Content-Type: application/json { "table": { "name": "my new table", "columns": [ { "name": "id", "type": "integer" }, { "name": "title", "type": "text" } ] "pk": "id" } } Supported column types are:

    • integer
    • text
    • float (even though SQLite calls it a "real")
    • blob

    This matches my design for sqlite-utils: https://sqlite-utils.datasette.io/en/stable/cli.html#cli-create-table

    {
        "total_count": 0,
        "+1": 0,
        "-1": 0,
        "laugh": 0,
        "hooray": 0,
        "confused": 0,
        "heart": 0,
        "rocket": 0,
        "eyes": 0
    }
    `/db/-/create` API for creating tables 1435294468  

    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 833.202ms · About: github-to-sqlite
    • Sort ascending
    • Sort descending
    • Facet by this
    • Hide this column
    • Show all columns
    • Show not-blank rows