home / github

Menu
  • Search all tables
  • GraphQL API

issue_comments

Table actions
  • GraphQL API for issue_comments

20 rows where author_association = "OWNER" and "created_at" is on date 2018-05-27 sorted by updated_at descending

✎ View and edit SQL

This data as json, CSV (advanced)

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

issue 6

  • Mechanism for customizing the SQL used to select specific columns in the table view 11
  • Avoid plugins accidentally loading dependencies twice 3
  • Handle spatialite geometry columns better 2
  • num_threads and cache_max_age should be --config options 2
  • metadata.json support for plugin configuration options 1
  • ?_shape=arrayfirst 1

user 1

  • simonw 20

author_association 1

  • OWNER · 20 ✖
id html_url issue_url node_id user created_at updated_at ▲ author_association body reactions issue performed_via_github_app
392343839 https://github.com/simonw/datasette/issues/292#issuecomment-392343839 https://api.github.com/repos/simonw/datasette/issues/292 MDEyOklzc3VlQ29tbWVudDM5MjM0MzgzOQ== simonw 9599 2018-05-27T16:10:09Z 2018-06-04T17:38:04Z OWNER

The more efficient way of doing this kind of count would be to provide a mechanism which can also add extra fragments to a GROUP BY clause used for the SELECT.

Or... how about a mechanism similar to Django's prefetch_related which lets you define extra queries that will be called with a list of primary keys (or values from other columns) and used to populate a new column? A little unconventional but could be extremely useful and efficient.

Related to that: since the per-query overhead in SQLite is tiny, could even define an extra query to be run once-per-row before returning results.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Mechanism for customizing the SQL used to select specific columns in the table view 326800219  
392350980 https://github.com/simonw/datasette/issues/292#issuecomment-392350980 https://api.github.com/repos/simonw/datasette/issues/292 MDEyOklzc3VlQ29tbWVudDM5MjM1MDk4MA== simonw 9599 2018-05-27T17:56:30Z 2018-05-27T17:56:50Z OWNER

Should ?_raw=1 also turn off foreign key expansions? No, we will eventually provide a separate mechanism for that (or leave it to nerds who care to figure out using JSON or CSV export).

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Mechanism for customizing the SQL used to select specific columns in the table view 326800219  
392350568 https://github.com/simonw/datasette/issues/292#issuecomment-392350568 https://api.github.com/repos/simonw/datasette/issues/292 MDEyOklzc3VlQ29tbWVudDM5MjM1MDU2OA== simonw 9599 2018-05-27T17:48:45Z 2018-05-27T17:54:41Z OWNER

If any ?_column= parameters are provided the metadata version is completely ignored.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Mechanism for customizing the SQL used to select specific columns in the table view 326800219  
392350495 https://github.com/simonw/datasette/issues/292#issuecomment-392350495 https://api.github.com/repos/simonw/datasette/issues/292 MDEyOklzc3VlQ29tbWVudDM5MjM1MDQ5NQ== simonw 9599 2018-05-27T17:47:31Z 2018-05-27T17:47:31Z OWNER

Querystring design:

  • ?_column=a&_column=b - equivalent of "columns": ["a", "b"] in metadata.json
  • ?_select_nameupper=upper(name) - equivalent of "column_selects": {"nameupper": "upper(name)"}
{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Mechanism for customizing the SQL used to select specific columns in the table view 326800219  
392345062 https://github.com/simonw/datasette/issues/292#issuecomment-392345062 https://api.github.com/repos/simonw/datasette/issues/292 MDEyOklzc3VlQ29tbWVudDM5MjM0NTA2Mg== simonw 9599 2018-05-27T16:26:53Z 2018-05-27T16:26:53Z OWNER

There needs to be a way to turn this off and return to Datasette default bahviour. Maybe a ?_raw=1 querystring parameter for the table view.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Mechanism for customizing the SQL used to select specific columns in the table view 326800219  
392343690 https://github.com/simonw/datasette/issues/292#issuecomment-392343690 https://api.github.com/repos/simonw/datasette/issues/292 MDEyOklzc3VlQ29tbWVudDM5MjM0MzY5MA== simonw 9599 2018-05-27T16:08:25Z 2018-05-27T16:08:40Z OWNER

Turns out it's actually possible to pull data from other tables using the mechanism in the prototype:

{ "databases": { "wtr": { "tables": { "license": { "column_selects": { "count": "(select count(*) from license_frequency where license_frequency.license = license.id)" } } } } } } Performance using this technique is pretty terrible though:

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Mechanism for customizing the SQL used to select specific columns in the table view 326800219  
392342947 https://github.com/simonw/datasette/issues/292#issuecomment-392342947 https://api.github.com/repos/simonw/datasette/issues/292 MDEyOklzc3VlQ29tbWVudDM5MjM0Mjk0Nw== simonw 9599 2018-05-27T16:01:43Z 2018-05-27T16:01:43Z OWNER

I'd still like to be able to over-ride this using querystring arguments.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Mechanism for customizing the SQL used to select specific columns in the table view 326800219  
392342269 https://github.com/simonw/datasette/issues/292#issuecomment-392342269 https://api.github.com/repos/simonw/datasette/issues/292 MDEyOklzc3VlQ29tbWVudDM5MjM0MjI2OQ== simonw 9599 2018-05-27T15:55:40Z 2018-05-27T16:01:26Z OWNER

Here's the metadata I tried against that first working prototype:

{ "databases": { "timezones": { "tables": { "timezones": { "columns": ["PK_UID"], "column_selects": { "upper_tzid": "upper(tzid)", "Geometry": "AsGeoJSON(Geometry)" } } } }, "wtr": { "tables": { "license_frequency": { "columns": ["id", "license", "tx_rx", "frequency"], "column_selects": { "latitude": "Y(Geometry)", "longitude": "X(Geometry)" } } } } } }

Run using this:

datasette timezones.db wtr.db \
    --reload --debug --load-extension=/usr/local/lib/mod_spatialite.dylib \
    -m column-metadata.json --config sql_time_limit_ms:10000

Usefully, the --reload flag detects changes to the metadata.json file as well as Datasette's own Python code.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Mechanism for customizing the SQL used to select specific columns in the table view 326800219  
392338130 https://github.com/simonw/datasette/issues/292#issuecomment-392338130 https://api.github.com/repos/simonw/datasette/issues/292 MDEyOklzc3VlQ29tbWVudDM5MjMzODEzMA== simonw 9599 2018-05-27T15:09:18Z 2018-05-27T15:09:28Z OWNER

Here's my first sketch at a metadata format for this:

  • columns: optional list of columns to include - if missing, shows all
  • column_selects: dictionary mapping column names to alternative select clauses

column_selects can also invent new keys and use them to create derived columns. These new keys will be selected at the end of the list of columns UNLESS they are mentioned in columns, in which case that sequence will define the order.

Can you facet by things that are customized using column_selects? Yes, and let's try running suggested facets against those columns as well. { "databases": { "databasename": { "tables": { "tablename": { "columns": [ "id", "name", "size" ], "column_selects": { "name": "upper(name)", "geo_json": "AsGeoJSON(Geometry)" } "row_columns": [...] "row_column_selects": {...} } The row_columns and row_column_selects properties work the same as the column* ones, except they are applied on the row page instead.

If omitted, the column* ones will be used on the row page as well.

If you want the row page to switch back to Datasette's default behaviour you can set "row_columns": [], "row_column_selects": {}.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Mechanism for customizing the SQL used to select specific columns in the table view 326800219  
392316701 https://github.com/simonw/datasette/issues/292#issuecomment-392316701 https://api.github.com/repos/simonw/datasette/issues/292 MDEyOklzc3VlQ29tbWVudDM5MjMxNjcwMQ== simonw 9599 2018-05-27T09:08:49Z 2018-05-27T09:08:49Z OWNER

I could certainly see people wanting different custom column selects for the row page compared to the table page.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Mechanism for customizing the SQL used to select specific columns in the table view 326800219  
392316673 https://github.com/simonw/datasette/issues/292#issuecomment-392316673 https://api.github.com/repos/simonw/datasette/issues/292 MDEyOklzc3VlQ29tbWVudDM5MjMxNjY3Mw== simonw 9599 2018-05-27T09:08:06Z 2018-05-27T09:08:06Z OWNER

Open question: how should this affect the row page? Just because columns were hidden on the table page doesn't necessarily mean they should be hidden on the row page as well.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Mechanism for customizing the SQL used to select specific columns in the table view 326800219  
392316306 https://github.com/simonw/datasette/issues/276#issuecomment-392316306 https://api.github.com/repos/simonw/datasette/issues/276 MDEyOklzc3VlQ29tbWVudDM5MjMxNjMwNg== simonw 9599 2018-05-27T09:00:46Z 2018-05-27T09:00:46Z OWNER

Relevant to this ticket: I've been playing with a plugin that automatically renders any GeoJSON cells as leaflet maps: https://github.com/simonw/datasette-leaflet-geojson

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Handle spatialite geometry columns better 324835838  
392316250 https://github.com/simonw/datasette/issues/276#issuecomment-392316250 https://api.github.com/repos/simonw/datasette/issues/276 MDEyOklzc3VlQ29tbWVudDM5MjMxNjI1MA== simonw 9599 2018-05-27T08:59:46Z 2018-05-27T08:59:46Z OWNER

It looks like we can use the geometry_columns table to introspect which columns are SpatiaLite geometries. It includes a geometry_type integer which is documented here: https://www.gaia-gis.it/fossil/libspatialite/wiki?name=switching-to-4.0

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Handle spatialite geometry columns better 324835838  
392305776 https://github.com/simonw/datasette/issues/231#issuecomment-392305776 https://api.github.com/repos/simonw/datasette/issues/231 MDEyOklzc3VlQ29tbWVudDM5MjMwNTc3Ng== simonw 9599 2018-05-27T05:10:46Z 2018-05-27T05:10:46Z OWNER

These plugin config options should be exposed to JavaScript as datasette.config.plugins

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
metadata.json support for plugin configuration options 316323336  
392302456 https://github.com/simonw/datasette/issues/291#issuecomment-392302456 https://api.github.com/repos/simonw/datasette/issues/291 MDEyOklzc3VlQ29tbWVudDM5MjMwMjQ1Ng== simonw 9599 2018-05-27T03:19:24Z 2018-05-27T03:19:24Z OWNER

The big gap in this solution is conflicting versions: I don't yet have a story for what happens if two plugins attempt to load different versions of Leaflet.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Avoid plugins accidentally loading dependencies twice 326783670  
392302416 https://github.com/simonw/datasette/issues/291#issuecomment-392302416 https://api.github.com/repos/simonw/datasette/issues/291 MDEyOklzc3VlQ29tbWVudDM5MjMwMjQxNg== simonw 9599 2018-05-27T03:18:16Z 2018-05-27T03:18:16Z OWNER

For the moment then I'm going with a really simple solution: when iterating through extra_css_urls and extra_js_urls de-dupe by URL and avoid outputting the same link twice.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Avoid plugins accidentally loading dependencies twice 326783670  
392302406 https://github.com/simonw/datasette/issues/291#issuecomment-392302406 https://api.github.com/repos/simonw/datasette/issues/291 MDEyOklzc3VlQ29tbWVudDM5MjMwMjQwNg== simonw 9599 2018-05-27T03:18:06Z 2018-05-27T03:18:06Z OWNER

My first attempt at this was to have plugins depend on each other - so there would be a datasette-leaflet plugin which adds Leaflet to the page, and the datasette-cluster-map and datasette-leaflet-geojson plugins would depend on that plugin.

I tried this and it didn't work, because it turns out the order in which plugins are loaded isn't predictable. datasette-cluster-map ended up adding it's script link before Leaflet had been loaded by datasette-leaflet, resulting in JavaScript errors.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Avoid plugins accidentally loading dependencies twice 326783670  
392297508 https://github.com/simonw/datasette/issues/285#issuecomment-392297508 https://api.github.com/repos/simonw/datasette/issues/285 MDEyOklzc3VlQ29tbWVudDM5MjI5NzUwOA== simonw 9599 2018-05-27T00:53:35Z 2018-05-27T00:53:35Z OWNER

Documentation: http://datasette.readthedocs.io/en/latest/config.html#num-sql-threads

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
num_threads and cache_max_age should be --config options 326189744  
392297392 https://github.com/simonw/datasette/issues/285#issuecomment-392297392 https://api.github.com/repos/simonw/datasette/issues/285 MDEyOklzc3VlQ29tbWVudDM5MjI5NzM5Mg== simonw 9599 2018-05-27T00:50:27Z 2018-05-27T00:50:27Z OWNER

I ran a very rough micro-benchmark on the new num_sql_threads config option.

datasette --config num_sql_threads:1 fivethirtyeight.db

Then

ab -n 100 -c 10 'http://127.0.0.1:8011/fivethirtyeight-2628db9/twitter-ratio%2Fsenators'

| Number of threads | Requests/second | |---|---| | 1 | 4.57 | | 3 | 9.77 | | 10 | 13.53 | | 20 | 15.24 | 50 | 8.21 |

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
num_threads and cache_max_age should be --config options 326189744  
392296758 https://github.com/simonw/datasette/issues/287#issuecomment-392296758 https://api.github.com/repos/simonw/datasette/issues/287 MDEyOklzc3VlQ29tbWVudDM5MjI5Njc1OA== simonw 9599 2018-05-27T00:32:53Z 2018-05-27T00:32:53Z OWNER

Docs: https://datasette.readthedocs.io/en/latest/json_api.html#different-shapes

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
?_shape=arrayfirst 326617744  

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 462.054ms · About: github-to-sqlite