home / github

Menu
  • Search all tables
  • GraphQL API

issue_comments

Table actions
  • GraphQL API for issue_comments

13 rows where "updated_at" is on date 2017-10-25 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 7

  • Experiment with patterns for concurrent long running queries 4
  • Support Django-style filters in querystring arguments 3
  • Protect against malicious SQL that causes damage even though our DB is immutable 2
  • Default HTML/CSS needs to look reasonable and be responsive 1
  • Efficient url for downloading the raw database file 1
  • Ability to serialize massive JSON without blocking event loop 1
  • Implement command-line tool interface 1

user 1

  • simonw 13

author_association 1

  • OWNER 13
id html_url issue_url node_id user created_at updated_at ▲ author_association body reactions issue performed_via_github_app
339420462 https://github.com/simonw/datasette/issues/16#issuecomment-339420462 https://api.github.com/repos/simonw/datasette/issues/16 MDEyOklzc3VlQ29tbWVudDMzOTQyMDQ2Mg== simonw 9599 2017-10-25T18:10:51Z 2017-10-25T18:10:51Z OWNER

https://sitesforprofit.com/responsive-table-plugins-and-patterns has some useful links.

I really like the pattern from https://css-tricks.com/responsive-data-tables/

/* 
Max width before this PARTICULAR table gets nasty
This query will take effect for any screen smaller than 760px
and also iPads specifically.
*/
@media 
only screen and (max-width: 760px),
(min-device-width: 768px) and (max-device-width: 1024px)  {

    /* Force table to not be like tables anymore */
    table, thead, tbody, th, td, tr { 
        display: block; 
    }

    /* Hide table headers (but not display: none;, for accessibility) */
    thead tr { 
        position: absolute;
        top: -9999px;
        left: -9999px;
    }

    tr { border: 1px solid #ccc; }

    td { 
        /* Behave  like a "row" */
        border: none;
        border-bottom: 1px solid #eee; 
        position: relative;
        padding-left: 50%; 
    }

    td:before { 
        /* Now like a table header */
        position: absolute;
        /* Top/left values mimic padding */
        top: 6px;
        left: 6px;
        width: 45%; 
        padding-right: 10px; 
        white-space: nowrap;
    }

    /*
    Label the data
    */
    td:nth-of-type(1):before { content: "First Name"; }
    td:nth-of-type(2):before { content: "Last Name"; }
    td:nth-of-type(3):before { content: "Job Title"; }
    td:nth-of-type(4):before { content: "Favorite Color"; }
    td:nth-of-type(5):before { content: "Wars of Trek?"; }
    td:nth-of-type(6):before { content: "Porn Name"; }
    td:nth-of-type(7):before { content: "Date of Birth"; }
    td:nth-of-type(8):before { content: "Dream Vacation City"; }
    td:nth-of-type(9):before { content: "GPA"; }
    td:nth-of-type(10):before { content: "Arbitrary Data"; }
}
{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Default HTML/CSS needs to look reasonable and be responsive 267726219  
339413825 https://github.com/simonw/datasette/issues/39#issuecomment-339413825 https://api.github.com/repos/simonw/datasette/issues/39 MDEyOklzc3VlQ29tbWVudDMzOTQxMzgyNQ== simonw 9599 2017-10-25T17:48:48Z 2017-10-25T17:48:48Z OWNER

Could I use https://sqlparse.readthedocs.io/en/latest/ to parse incoming statements and ensure they are pure SELECTs? Would that prevent people from using a compound SELECT statement to trigger an evil PRAGMA of some sort?

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Protect against malicious SQL that causes damage even though our DB is immutable 268469569  
339406634 https://github.com/simonw/datasette/issues/39#issuecomment-339406634 https://api.github.com/repos/simonw/datasette/issues/39 MDEyOklzc3VlQ29tbWVudDMzOTQwNjYzNA== simonw 9599 2017-10-25T17:27:10Z 2017-10-25T17:27:10Z OWNER

It certainly looks like some of the stuff in https://sqlite.org/pragma.html could be used to screw around with things. Example: PRAGMA case_sensitive_like = 1 - would that affect future queries?

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Protect against malicious SQL that causes damage even though our DB is immutable 268469569  
339395551 https://github.com/simonw/datasette/issues/40#issuecomment-339395551 https://api.github.com/repos/simonw/datasette/issues/40 MDEyOklzc3VlQ29tbWVudDMzOTM5NTU1MQ== simonw 9599 2017-10-25T16:49:32Z 2017-10-25T16:49:32Z OWNER

Simplest implementation will be to create a temporary directory somewhere, copy in a Dockerfile and the databases and run “now” in it.

Ideally I can use symlinks rather than copying potentially large database files around.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Implement command-line tool interface 268470572  
339389328 https://github.com/simonw/datasette/issues/38#issuecomment-339389328 https://api.github.com/repos/simonw/datasette/issues/38 MDEyOklzc3VlQ29tbWVudDMzOTM4OTMyOA== simonw 9599 2017-10-25T16:29:23Z 2017-10-25T16:29:23Z OWNER

Ideally we can get some serious gains from the fact that our database file is opened with the immutable option.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Experiment with patterns for concurrent long running queries 268462768  
339389105 https://github.com/simonw/datasette/issues/38#issuecomment-339389105 https://api.github.com/repos/simonw/datasette/issues/38 MDEyOklzc3VlQ29tbWVudDMzOTM4OTEwNQ== simonw 9599 2017-10-25T16:28:39Z 2017-10-25T16:28:39Z OWNER

The gold standard here is to be able to serve up increasingly large datasets without blocking the event loop and while using a sustainable amount of RAM

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Experiment with patterns for concurrent long running queries 268462768  
339388771 https://github.com/simonw/datasette/issues/38#issuecomment-339388771 https://api.github.com/repos/simonw/datasette/issues/38 MDEyOklzc3VlQ29tbWVudDMzOTM4ODc3MQ== simonw 9599 2017-10-25T16:27:29Z 2017-10-25T16:27:29Z OWNER

If this does work, I need to figure it what to do about the HTML view. ASsuming I can iteratively produce JSON and CSV, what to do about HTML? One option: render the first 500 rows as HTML, then hand off to an infinite scroll experience that iteratively loads more rows as JSON.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Experiment with patterns for concurrent long running queries 268462768  
339388215 https://github.com/simonw/datasette/issues/38#issuecomment-339388215 https://api.github.com/repos/simonw/datasette/issues/38 MDEyOklzc3VlQ29tbWVudDMzOTM4ODIxNQ== simonw 9599 2017-10-25T16:25:45Z 2017-10-25T16:25:45Z OWNER

First experiment: hook up an iterative CSV dump (just because that’s a tiny bit easier to get started with than iterative a JSON). Have it execute a big select statement and then iterate through the result set 100 rows at a time using sqite fetchmany() - also have it async sleep for a second in between each batch of 100.

Can this work without needing python threads?

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Experiment with patterns for concurrent long running queries 268462768  
339382054 https://github.com/simonw/datasette/issues/37#issuecomment-339382054 https://api.github.com/repos/simonw/datasette/issues/37 MDEyOklzc3VlQ29tbWVudDMzOTM4MjA1NA== simonw 9599 2017-10-25T16:05:56Z 2017-10-25T16:05:56Z OWNER

Could this be as simple as using the iterative JSON encoder and adding a yield statement in between each chunk?

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Ability to serialize massive JSON without blocking event loop 268453968  
339366612 https://github.com/simonw/datasette/issues/19#issuecomment-339366612 https://api.github.com/repos/simonw/datasette/issues/19 MDEyOklzc3VlQ29tbWVudDMzOTM2NjYxMg== simonw 9599 2017-10-25T15:21:16Z 2017-10-25T15:21:16Z OWNER

I had to manually set the content disposition header:

return await response.file_stream(
    filepath, headers={
        'Content-Disposition': 'attachment; filename="{}"'.format(ilepath)
    }
)

In the next release of Sanic I can just use the filename= argument instead:

https://github.com/channelcat/sanic/commit/07e95dba4f5983afc1e673df14bdd278817288aa

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Efficient url for downloading the raw database file 267741262  
339210353 https://github.com/simonw/datasette/issues/23#issuecomment-339210353 https://api.github.com/repos/simonw/datasette/issues/23 MDEyOklzc3VlQ29tbWVudDMzOTIxMDM1Mw== simonw 9599 2017-10-25T04:23:02Z 2017-10-25T04:23:02Z OWNER

I'm going to call this one done for the moment. The date filters can go in a stretch goal.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Support Django-style filters in querystring arguments 267788884  
339186887 https://github.com/simonw/datasette/issues/23#issuecomment-339186887 https://api.github.com/repos/simonw/datasette/issues/23 MDEyOklzc3VlQ29tbWVudDMzOTE4Njg4Nw== simonw 9599 2017-10-25T01:39:43Z 2017-10-25T04:22:41Z OWNER

Still to do:

  • [x] gt, gte, lt, lte
  • [x] like
  • [x] glob
{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Support Django-style filters in querystring arguments 267788884  
338854988 https://github.com/simonw/datasette/issues/23#issuecomment-338854988 https://api.github.com/repos/simonw/datasette/issues/23 MDEyOklzc3VlQ29tbWVudDMzODg1NDk4OA== simonw 9599 2017-10-24T02:40:12Z 2017-10-25T00:05:46Z OWNER
/database-name/table-name?name__contains=simon&sort=id+desc

Note that if there's a column called "sort" you can still do sort__exact=blah

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Support Django-style filters in querystring arguments 267788884  

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