home / github

Menu
  • Search all tables
  • GraphQL API

issue_comments

Table actions
  • GraphQL API for issue_comments

26 rows where "updated_at" is on date 2018-04-16 and user = 9599 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 8

  • Bug: Sort by column with NULL in next_page URL 8
  • Load plugins from a `--plugins-dir=plugins/` directory 6
  • Datasette Plugins 5
  • Ability for plugins to define extra JavaScript and CSS 3
  • Build a visualization plugin for Vega 1
  • Figure out how to bundle a more up-to-date SQLite 1
  • Don't duplicate simple primary keys in the link column 1
  • Investigate syntactic sugar for plugins 1

user 1

  • simonw · 26 ✖

author_association 1

  • OWNER 26
id html_url issue_url node_id user created_at updated_at ▲ author_association body reactions issue performed_via_github_app
381786522 https://github.com/simonw/datasette/issues/216#issuecomment-381786522 https://api.github.com/repos/simonw/datasette/issues/216 MDEyOklzc3VlQ29tbWVudDM4MTc4NjUyMg== simonw 9599 2018-04-16T23:58:45Z 2018-04-16T23:59:13Z OWNER

Weird... tests are failing in Travis, despite passing on my local machine. https://travis-ci.org/simonw/datasette/builds/367423706

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Bug: Sort by column with NULL in next_page URL 314665147  
381777108 https://github.com/simonw/datasette/issues/220#issuecomment-381777108 https://api.github.com/repos/simonw/datasette/issues/220 MDEyOklzc3VlQ29tbWVudDM4MTc3NzEwOA== simonw 9599 2018-04-16T23:04:04Z 2018-04-16T23:04:04Z OWNER

This could also help workaround the current predicament that a single plugin can only define one prepare_connection hook.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Investigate syntactic sugar for plugins 314847571  
381649437 https://github.com/simonw/datasette/issues/216#issuecomment-381649437 https://api.github.com/repos/simonw/datasette/issues/216 MDEyOklzc3VlQ29tbWVudDM4MTY0OTQzNw== simonw 9599 2018-04-16T15:39:21Z 2018-04-16T15:39:21Z OWNER

Here's where that SQL gets constructed at the moment:

https://github.com/simonw/datasette/blob/10a34f995c70daa37a8a2aa02c3135a4b023a24c/datasette/app.py#L761-L771

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Bug: Sort by column with NULL in next_page URL 314665147  
381649140 https://github.com/simonw/datasette/issues/216#issuecomment-381649140 https://api.github.com/repos/simonw/datasette/issues/216 MDEyOklzc3VlQ29tbWVudDM4MTY0OTE0MA== simonw 9599 2018-04-16T15:38:29Z 2018-04-16T15:38:29Z OWNER

But what would that SQL look like for _sort_desc?

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Bug: Sort by column with NULL in next_page URL 314665147  
381648053 https://github.com/simonw/datasette/issues/216#issuecomment-381648053 https://api.github.com/repos/simonw/datasette/issues/216 MDEyOklzc3VlQ29tbWVudDM4MTY0ODA1Mw== simonw 9599 2018-04-16T15:35:17Z 2018-04-16T15:35:17Z OWNER

I think the correct SQL is this: https://datasette-issue-189-demo-3.now.sh/salaries-7859114-7859114?sql=select+rowid%2C+*+from+%5B2017+Maryland+state+salaries%5D%0D%0Awhere+%28middle_initial+is+not+null+or+%28middle_initial+is+null+and+rowid+%3E+%3Ap0%29%29%0D%0Aorder+by+middle_initial+limit+101&p0=391

select rowid, * from [2017 Maryland state salaries] where (middle_initial is not null or (middle_initial is null and rowid > :p0)) order by middle_initial limit 101

Though this will also need to be taken into account for #198

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Bug: Sort by column with NULL in next_page URL 314665147  
381645973 https://github.com/simonw/datasette/issues/216#issuecomment-381645973 https://api.github.com/repos/simonw/datasette/issues/216 MDEyOklzc3VlQ29tbWVudDM4MTY0NTk3Mw== simonw 9599 2018-04-16T15:29:11Z 2018-04-16T15:29:11Z OWNER

I could use $null as a magic value that means None. Since I'm applying quote_plus() to actual values, any legit strings that look like this will be encoded as %24null:

```

urllib.parse.quote_plus('$null') '%24null' ```

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Bug: Sort by column with NULL in next_page URL 314665147  
381645274 https://github.com/simonw/datasette/issues/216#issuecomment-381645274 https://api.github.com/repos/simonw/datasette/issues/216 MDEyOklzc3VlQ29tbWVudDM4MTY0NTI3NA== simonw 9599 2018-04-16T15:27:16Z 2018-04-16T15:27:16Z OWNER

Relevant code:

https://github.com/simonw/datasette/blob/904f1c75a3c17671d25c53b91e177c249d14ab3b/datasette/app.py#L828-L832

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Bug: Sort by column with NULL in next_page URL 314665147  
381644355 https://github.com/simonw/datasette/issues/216#issuecomment-381644355 https://api.github.com/repos/simonw/datasette/issues/216 MDEyOklzc3VlQ29tbWVudDM4MTY0NDM1NQ== simonw 9599 2018-04-16T15:24:38Z 2018-04-16T15:24:38Z OWNER

So there are two tricky problems to solve here:

  • I need a way of encoding null into that _next= that is unambiguous from the string None or null. This means introducing some kind of escaping mechanism in those strings. I already use URL encoding as part of the construction of those components here, maybe that can help here?
  • I need to figure out what the SQL should be for the "next" set of results if the previous value was null. Thankfully we use the primary key as a tie-breaker so this shouldn't be impossible.
{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Bug: Sort by column with NULL in next_page URL 314665147  
381643173 https://github.com/simonw/datasette/issues/216#issuecomment-381643173 https://api.github.com/repos/simonw/datasette/issues/216 MDEyOklzc3VlQ29tbWVudDM4MTY0MzE3Mw== simonw 9599 2018-04-16T15:21:17Z 2018-04-16T15:21:17Z OWNER

Yikes, definitely a bug.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Bug: Sort by column with NULL in next_page URL 314665147  
381621338 https://github.com/simonw/datasette/issues/14#issuecomment-381621338 https://api.github.com/repos/simonw/datasette/issues/14 MDEyOklzc3VlQ29tbWVudDM4MTYyMTMzOA== simonw 9599 2018-04-16T14:36:27Z 2018-04-16T14:36:27Z OWNER

Annoyingly, the following only results in the last of the two prepare_connection hooks being registered:

``` from datasette import hookimpl import pint import random

ureg = pint.UnitRegistry()

@hookimpl def prepare_connection(conn): def convert_units(amount, from_, to_): "select convert_units(100, 'm', 'ft');" return (amount * ureg(from_)).to(to_).to_tuple()[0] conn.create_function('convert_units', 3, convert_units)

@hookimpl def prepare_connection(conn): conn.create_function('random_integer', 2, random.randint) ```

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Datasette Plugins 267707940  
381612585 https://github.com/simonw/datasette/issues/214#issuecomment-381612585 https://api.github.com/repos/simonw/datasette/issues/214 MDEyOklzc3VlQ29tbWVudDM4MTYxMjU4NQ== simonw 9599 2018-04-16T14:10:16Z 2018-04-16T14:10:16Z OWNER

resource_stream returns a file-like object which may be better for serving from Sanic.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Ability for plugins to define extra JavaScript and CSS 314506446  
381611738 https://github.com/simonw/datasette/issues/14#issuecomment-381611738 https://api.github.com/repos/simonw/datasette/issues/14 MDEyOklzc3VlQ29tbWVudDM4MTYxMTczOA== simonw 9599 2018-04-16T14:07:30Z 2018-04-16T14:07:30Z OWNER

I should check if it's possible to have two template registration function plugins in a single plugin module. If it isn't maybe I should use class plugins instead of module plugins.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Datasette Plugins 267707940  
381491707 https://github.com/simonw/datasette/issues/214#issuecomment-381491707 https://api.github.com/repos/simonw/datasette/issues/214 MDEyOklzc3VlQ29tbWVudDM4MTQ5MTcwNw== simonw 9599 2018-04-16T06:21:23Z 2018-04-16T06:21:23Z OWNER

This looks like a good example: https://github.com/funkey/nyroglancer/commit/d4438ab42171360b2b8e9020f672846dd70c8d80

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Ability for plugins to define extra JavaScript and CSS 314506446  
381490361 https://github.com/simonw/datasette/issues/214#issuecomment-381490361 https://api.github.com/repos/simonw/datasette/issues/214 MDEyOklzc3VlQ29tbWVudDM4MTQ5MDM2MQ== simonw 9599 2018-04-16T06:13:02Z 2018-04-16T06:13:02Z OWNER

Packaging JS and CSS in a pip installable wheel is fiddly but possible. http://peak.telecommunity.com/DevCenter/PythonEggs#accessing-package-resources

from pkg_resources import resource_string
foo_config = resource_string(__name__, 'foo.conf')
{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Ability for plugins to define extra JavaScript and CSS 314506446  
381488049 https://github.com/simonw/datasette/issues/191#issuecomment-381488049 https://api.github.com/repos/simonw/datasette/issues/191 MDEyOklzc3VlQ29tbWVudDM4MTQ4ODA0OQ== simonw 9599 2018-04-16T05:58:15Z 2018-04-16T05:58:15Z OWNER

I think this is pretty hard. @coleifer has done some work in this direction, including https://github.com/coleifer/pysqlite3 which ports the standalone pysqlite module to Python 3.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Figure out how to bundle a more up-to-date SQLite 310533258  
381446392 https://github.com/simonw/datasette/issues/14#issuecomment-381446392 https://api.github.com/repos/simonw/datasette/issues/14 MDEyOklzc3VlQ29tbWVudDM4MTQ0NjM5Mg== simonw 9599 2018-04-15T23:22:40Z 2018-04-16T05:25:57Z OWNER

OK, from that prototype in f2720b0c6b7172ebe8820 it looks like pluggy provides a solid path forward.

Next steps:

  • [x] Build a demo plugin that uses setuptools entrypoints to register with the datasette plugin manager via pluggy
  • [x] Figure out a mechanism for registering plugins without first needing to publish them to PyPI. Can I load plugins from a special plugins/ directory similar to the --template-dir=templates/ option already supported by Datasette? #211
{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Datasette Plugins 267707940  
381483301 https://github.com/simonw/datasette/pull/209#issuecomment-381483301 https://api.github.com/repos/simonw/datasette/issues/209 MDEyOklzc3VlQ29tbWVudDM4MTQ4MzMwMQ== simonw 9599 2018-04-16T05:25:08Z 2018-04-16T05:25:08Z OWNER

I think this is a good improvement. If you fix the tests I'll merge it.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Don't duplicate simple primary keys in the link column 314455877  
381482407 https://github.com/simonw/datasette/issues/211#issuecomment-381482407 https://api.github.com/repos/simonw/datasette/issues/211 MDEyOklzc3VlQ29tbWVudDM4MTQ4MjQwNw== simonw 9599 2018-04-16T05:18:29Z 2018-04-16T05:18:29Z OWNER

Here's the result of running this:

datasette publish heroku fivethirtyeight.db \
    --plugins-dir=plugins/ --title="FiveThirtyEight" --branch=plugins-dir

https://intense-river-24599.herokuapp.com/fivethirtyeight-2628db9?sql=select+convert_units%28100%2C+%27m%27%2C+%27ft%27%29

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Load plugins from a `--plugins-dir=plugins/` directory 314471743  
381481990 https://github.com/simonw/datasette/issues/211#issuecomment-381481990 https://api.github.com/repos/simonw/datasette/issues/211 MDEyOklzc3VlQ29tbWVudDM4MTQ4MTk5MA== simonw 9599 2018-04-16T05:14:57Z 2018-04-16T05:14:57Z OWNER

Added unit tests in 33c6bcadb962457be6b0c7f369826b404e2bcef5

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Load plugins from a `--plugins-dir=plugins/` directory 314471743  
381478253 https://github.com/simonw/datasette/issues/211#issuecomment-381478253 https://api.github.com/repos/simonw/datasette/issues/211 MDEyOklzc3VlQ29tbWVudDM4MTQ3ODI1Mw== simonw 9599 2018-04-16T04:42:02Z 2018-04-16T04:42:02Z OWNER

This worked as well:

datasette package fivethirtyeight.db \
    --plugins-dir=plugins/ --title="FiveThirtyEight" --branch=plugins-dir
{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Load plugins from a `--plugins-dir=plugins/` directory 314471743  
381478217 https://github.com/simonw/datasette/issues/211#issuecomment-381478217 https://api.github.com/repos/simonw/datasette/issues/211 MDEyOklzc3VlQ29tbWVudDM4MTQ3ODIxNw== simonw 9599 2018-04-16T04:41:38Z 2018-04-16T04:41:38Z OWNER

Here's the result of running:

datasette publish now fivethirtyeight.db \
    --plugins-dir=plugins/ --title="FiveThirtyEight" --branch=plugins-dir

https://datasette-phjtvzwwzl.now.sh/fivethirtyeight-2628db9?sql=select+convert_units%28100%2C+%27m%27%2C+%27ft%27%29

Where plugins/pint_plugin.py contains the following: ``` from datasette import hookimpl import pint

ureg = pint.UnitRegistry()

@hookimpl def prepare_connection(conn): def convert_units(amount, from_, to_): "select convert_units(100, 'm', 'ft');" return (amount * ureg(from_)).to(to_).to_tuple()[0] conn.create_function('convert_units', 3, convert_units) ```

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Load plugins from a `--plugins-dir=plugins/` directory 314471743  
381462005 https://github.com/simonw/datasette/issues/211#issuecomment-381462005 https://api.github.com/repos/simonw/datasette/issues/211 MDEyOklzc3VlQ29tbWVudDM4MTQ2MjAwNQ== simonw 9599 2018-04-16T02:23:07Z 2018-04-16T02:23:07Z OWNER

This needs unit tests. I also need to manually test the datasette package and datesette publish commands.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Load plugins from a `--plugins-dir=plugins/` directory 314471743  
381456434 https://github.com/simonw/datasette/issues/211#issuecomment-381456434 https://api.github.com/repos/simonw/datasette/issues/211 MDEyOklzc3VlQ29tbWVudDM4MTQ1NjQzNA== simonw 9599 2018-04-16T01:36:16Z 2018-04-16T01:37:44Z OWNER

The easiest way to implement this in Python 2 would be execfile(...) - but that was removed in Python 3. According to https://stackoverflow.com/a/437857/6083 2to3 replaces that with this, which ensures the filename is associated with the code for debugging purposes:

with open("somefile.py") as f: code = compile(f.read(), "somefile.py", 'exec') exec(code, global_vars, local_vars)

Implementing it this way would force this kind of plugin to be self-contained in a single file. I think that's OK: if you want a more complex plugin you can use the standard pluggy-powered setuptools mechanism to build it.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Load plugins from a `--plugins-dir=plugins/` directory 314471743  
381455054 https://github.com/simonw/datasette/issues/139#issuecomment-381455054 https://api.github.com/repos/simonw/datasette/issues/139 MDEyOklzc3VlQ29tbWVudDM4MTQ1NTA1NA== simonw 9599 2018-04-16T01:24:13Z 2018-04-16T01:24:13Z OWNER

I think Vega-Lite is the way to go here: https://vega.github.io/vega-lite/

I've been playing around with it and Datasette with some really positive initial results:

https://vega.github.io/editor/#/gist/vega-lite/simonw/89100ce80573d062d70f780d10e5e609/decada131575825875c0a076e418c661c2adb014/vice-shootings-gender-race-by-department.vl.json

https://vega.github.io/editor/#/gist/vega-lite/simonw/5f69fbe29380b0d5d95f31a385f49ee4/7087b64df03cf9dba44a5258a606f29182cb8619/trees-san-francisco.vl.json

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Build a visualization plugin for Vega 275493851  
381450591 https://github.com/simonw/datasette/issues/14#issuecomment-381450591 https://api.github.com/repos/simonw/datasette/issues/14 MDEyOklzc3VlQ29tbWVudDM4MTQ1MDU5MQ== simonw 9599 2018-04-16T00:30:22Z 2018-04-16T00:34:42Z OWNER

Slight code design problem... when I tried installing my branch in a fresh virtual environment I got this error, because setup.py now depends on pluggy (from importing __version__):

File "/private/var/folders/jj/fngnv0810tn2lt_kd3911pdc0000gp/T/pip-req-build-dftqdezt/setup.py", line 2, in <module> from datasette import __version__ File "/private/var/folders/jj/fngnv0810tn2lt_kd3911pdc0000gp/T/pip-req-build-dftqdezt/datasette/__init__.py", line 2, in <module> from .hookspecs import hookimpl # noqa File "/private/var/folders/jj/fngnv0810tn2lt_kd3911pdc0000gp/T/pip-req-build-dftqdezt/datasette/hookspecs.py", line 1, in <module> from pluggy import HookimplMarker ModuleNotFoundError: No module named 'pluggy'

Looks like I've run into point 6 on https://packaging.python.org/guides/single-sourcing-package-version/ :

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Datasette Plugins 267707940  
381450394 https://github.com/simonw/datasette/issues/14#issuecomment-381450394 https://api.github.com/repos/simonw/datasette/issues/14 MDEyOklzc3VlQ29tbWVudDM4MTQ1MDM5NA== simonw 9599 2018-04-16T00:27:23Z 2018-04-16T00:27:23Z OWNER

I created https://github.com/simonw/datasette-plugin-demos which is now published to PyPI and can be installed with pip install datasette-plugin-demos - I've confirmed that if you DO install it my Datasette plugins branch picks up the plugins, and select random_integer(1, 4) works as it should.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Datasette Plugins 267707940  

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