issue_comments
8,358 rows where author_association = "OWNER" and user = 9599 sorted by updated_at descending
This data as json, CSV (advanced)
user 1
- simonw · 3,816 ✖
id | html_url | issue_url | node_id | user | created_at | updated_at ▲ | author_association | body | reactions | issue | performed_via_github_app |
---|---|---|---|---|---|---|---|---|---|---|---|
752274509 | https://github.com/simonw/datasette/issues/1160#issuecomment-752274509 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MjI3NDUwOQ== | simonw 9599 | 2020-12-29T23:26:02Z | 2020-12-29T23:26:02Z | OWNER | The documentation for this plugin hook is going to be pretty detailed, since it involves writing custom classes. I'll stick it all on the existing hooks page for the moment, but I should think about breaking up the plugin hook documentation into a page-per-hook in the future. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
752274340 | https://github.com/simonw/datasette/issues/1163#issuecomment-752274340 | https://api.github.com/repos/simonw/datasette/issues/1163 | MDEyOklzc3VlQ29tbWVudDc1MjI3NDM0MA== | simonw 9599 | 2020-12-29T23:25:02Z | 2020-12-29T23:25:02Z | OWNER | This will be built on top of |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert data.db url-to-csv" 776128565 | |
752274078 | https://github.com/simonw/datasette/issues/1160#issuecomment-752274078 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MjI3NDA3OA== | simonw 9599 | 2020-12-29T23:23:39Z | 2020-12-29T23:23:39Z | OWNER | If I design this right I can ship a full version of the command-line |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
752273873 | https://github.com/simonw/datasette/issues/1160#issuecomment-752273873 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MjI3Mzg3Mw== | simonw 9599 | 2020-12-29T23:22:30Z | 2020-12-29T23:22:30Z | OWNER | How much of this should I get done in a branch before merging into The challenge here is the plugin hook design: ideally I don't want an incomplete plugin hook design in |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
752273400 | https://github.com/simonw/datasette/issues/1160#issuecomment-752273400 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MjI3MzQwMA== | simonw 9599 | 2020-12-29T23:19:46Z | 2020-12-29T23:19:46Z | OWNER | I'm going to break out some separate tickets. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
752273306 | https://github.com/simonw/datasette/issues/1160#issuecomment-752273306 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MjI3MzMwNg== | simonw 9599 | 2020-12-29T23:19:15Z | 2020-12-29T23:19:15Z | OWNER | It would be nice if this abstraction could support progress bars as well. These won't necessarily work for every format - or they might work for things loaded from files but not things loaded over URLs (if the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
752267905 | https://github.com/simonw/datasette/issues/1160#issuecomment-752267905 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MjI2NzkwNQ== | simonw 9599 | 2020-12-29T22:52:09Z | 2020-12-29T22:52:09Z | OWNER | What's the simplest thing that could possible work? I think it's |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
752266076 | https://github.com/simonw/datasette/issues/1160#issuecomment-752266076 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MjI2NjA3Ng== | simonw 9599 | 2020-12-29T22:42:23Z | 2020-12-29T22:42:59Z | OWNER | Aside: maybe This would be useful for import mechanisms that are likely to need their own custom set of command-line options unique to that source. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
752265600 | https://github.com/simonw/datasette/issues/1160#issuecomment-752265600 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MjI2NTYwMA== | simonw 9599 | 2020-12-29T22:39:56Z | 2020-12-29T22:39:56Z | OWNER | Does it definitely make sense to break this operation up into the code that turns the incoming format into a iterator of dictionaries, then the code that inserts those into the database using That seems right for simple imports, where the incoming file represents a sequence of records in a single table. But what about more complex formats? What if a format needs to be represented as multiple tables? |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
752259345 | https://github.com/simonw/datasette/issues/1160#issuecomment-752259345 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MjI1OTM0NQ== | simonw 9599 | 2020-12-29T22:11:54Z | 2020-12-29T22:11:54Z | OWNER | Important detail from https://docs.python.org/3/library/csv.html#csv.reader
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
752257666 | https://github.com/simonw/datasette/issues/1160#issuecomment-752257666 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MjI1NzY2Ng== | simonw 9599 | 2020-12-29T22:09:18Z | 2020-12-29T22:09:18Z | OWNER | Figuring out the API designI want to be able to support different formats, and be able to parse them into tables either streaming or in one go depending on if the format supports that. Ideally I want to be able to pull the first 1,024 bytes for the purpose of detecting the format, then replay those bytes again later. I'm considering this a stretch goal though. CSV is easy to parse as a stream - here’s how sqlite-utils does it:
Problem: using |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
752253095 | https://github.com/simonw/datasette/issues/1161#issuecomment-752253095 | https://api.github.com/repos/simonw/datasette/issues/1161 | MDEyOklzc3VlQ29tbWVudDc1MjI1MzA5NQ== | simonw 9599 | 2020-12-29T21:49:57Z | 2020-12-29T21:49:57Z | OWNER | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Update a whole bunch of links to datasette.io instead of datasette.readthedocs.io 776101101 | ||
752236520 | https://github.com/simonw/datasette/issues/1160#issuecomment-752236520 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MjIzNjUyMA== | simonw 9599 | 2020-12-29T20:48:51Z | 2020-12-29T20:48:51Z | OWNER | It would be neat if |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
751925934 | https://github.com/simonw/datasette/issues/1160#issuecomment-751925934 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MTkyNTkzNA== | simonw 9599 | 2020-12-29T02:40:13Z | 2020-12-29T20:25:57Z | OWNER | Basic command design:
The options can include:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
752208036 | https://github.com/simonw/datasette/issues/1160#issuecomment-752208036 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MjIwODAzNg== | simonw 9599 | 2020-12-29T19:06:35Z | 2020-12-29T19:06:35Z | OWNER | If I'm going to execute 1000s of writes in an https://stackoverflow.com/a/36648102 and https://github.com/python/asyncio/issues/284 confirm that |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
752203909 | https://github.com/simonw/datasette/issues/1160#issuecomment-752203909 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MjIwMzkwOQ== | simonw 9599 | 2020-12-29T18:54:19Z | 2020-12-29T18:54:19Z | OWNER | More thoughts on this: the key mechanism that populates the tables needs to be an |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
751947991 | https://github.com/simonw/datasette/issues/1160#issuecomment-751947991 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MTk0Nzk5MQ== | simonw 9599 | 2020-12-29T05:06:50Z | 2020-12-29T05:07:03Z | OWNER | Given the URL option could it be possible for plugins to "subscribe" to URLs that keep on streaming?
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
751946262 | https://github.com/simonw/datasette/issues/1160#issuecomment-751946262 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MTk0NjI2Mg== | simonw 9599 | 2020-12-29T04:56:12Z | 2020-12-29T04:56:32Z | OWNER | Potential design for this: a
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
751945094 | https://github.com/simonw/datasette/issues/1160#issuecomment-751945094 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MTk0NTA5NA== | simonw 9599 | 2020-12-29T04:48:11Z | 2020-12-29T04:48:11Z | OWNER | It would be pretty cool if you could launch Datasette directly against an insert-compatible file or URL without first having to load it into a SQLite database file. Or imagine being able to tail a log file and like that directly into a new Datasette process, which then runs a web server with the UI while simultaneously continuing to load new entries from that log into the in-memory SQLite database that it is serving... Not quite sure what that CLI interface would look like. Maybe treat that as a future stretch goal for the moment. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
751943837 | https://github.com/simonw/datasette/issues/1160#issuecomment-751943837 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MTk0MzgzNw== | simonw 9599 | 2020-12-29T04:40:30Z | 2020-12-29T04:40:30Z | OWNER | The It should accept more than one file name at a time for bulk inserts. if using a URL that URL will be passed to the method that decides if a plugin implementation can handle the import or not. This will allow plugins to register themselves for specific websites. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
751926437 | https://github.com/simonw/datasette/issues/1160#issuecomment-751926437 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MTkyNjQzNw== | simonw 9599 | 2020-12-29T02:43:21Z | 2020-12-29T02:43:37Z | OWNER | Default formats to support:
Each of these will be implemented as a default plugin. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
751926218 | https://github.com/simonw/datasette/issues/1160#issuecomment-751926218 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MTkyNjIxOA== | simonw 9599 | 2020-12-29T02:41:57Z | 2020-12-29T02:41:57Z | OWNER | Other names I considered:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
751926095 | https://github.com/simonw/datasette/issues/1160#issuecomment-751926095 | https://api.github.com/repos/simonw/datasette/issues/1160 | MDEyOklzc3VlQ29tbWVudDc1MTkyNjA5NQ== | simonw 9599 | 2020-12-29T02:41:15Z | 2020-12-29T02:41:15Z | OWNER | The UI can live at
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"datasette insert" command and plugin hook 775666296 | |
751826749 | https://github.com/simonw/datasette/issues/675#issuecomment-751826749 | https://api.github.com/repos/simonw/datasette/issues/675 | MDEyOklzc3VlQ29tbWVudDc1MTgyNjc0OQ== | simonw 9599 | 2020-12-28T18:49:21Z | 2020-12-28T18:49:21Z | OWNER | That |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
--cp option for datasette publish and datasette package for shipping additional files and directories 567902704 | |
751826621 | https://github.com/simonw/datasette/issues/675#issuecomment-751826621 | https://api.github.com/repos/simonw/datasette/issues/675 | MDEyOklzc3VlQ29tbWVudDc1MTgyNjYyMQ== | simonw 9599 | 2020-12-28T18:48:51Z | 2020-12-28T18:48:51Z | OWNER | I could make
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
--cp option for datasette publish and datasette package for shipping additional files and directories 567902704 | |
751127485 | https://github.com/simonw/datasette/issues/417#issuecomment-751127485 | https://api.github.com/repos/simonw/datasette/issues/417 | MDEyOklzc3VlQ29tbWVudDc1MTEyNzQ4NQ== | simonw 9599 | 2020-12-24T22:58:05Z | 2020-12-24T22:58:05Z | OWNER | That's a great idea. I'd ruled that out because working with the different operating system versions of those is tricky, but if |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Datasette Library 421546944 | |
750390741 | https://github.com/simonw/datasette/pull/1158#issuecomment-750390741 | https://api.github.com/repos/simonw/datasette/issues/1158 | MDEyOklzc3VlQ29tbWVudDc1MDM5MDc0MQ== | simonw 9599 | 2020-12-23T17:05:32Z | 2020-12-23T17:05:32Z | OWNER | Thanks for this! I'm fine keeping the |
{ "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Modernize code to Python 3.6+ 773913793 | |
750373603 | https://github.com/simonw/datasette/pull/1158#issuecomment-750373603 | https://api.github.com/repos/simonw/datasette/issues/1158 | MDEyOklzc3VlQ29tbWVudDc1MDM3MzYwMw== | simonw 9599 | 2020-12-23T16:26:21Z | 2020-12-23T16:26:21Z | OWNER | Did you use a tool to find these or are they all from manual code inspection? They look good - I particularly like the set/dict literals. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Modernize code to Python 3.6+ 773913793 | |
749845797 | https://github.com/simonw/datasette/issues/1099#issuecomment-749845797 | https://api.github.com/repos/simonw/datasette/issues/1099 | MDEyOklzc3VlQ29tbWVudDc0OTg0NTc5Nw== | simonw 9599 | 2020-12-23T00:13:29Z | 2020-12-23T00:14:25Z | OWNER | Also need to solve displaying these links in the opposite direction: https://latest.datasette.io/_internal/tables/fixtures,facet_cities That page should link to lists of records in columns, foreign_keys and indexes - like this example: https://latest.datasette.io/fixtures/roadside_attractions/1 |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Support linking to compound foreign keys 743371103 | |
748206874 | https://github.com/simonw/datasette/issues/1152#issuecomment-748206874 | https://api.github.com/repos/simonw/datasette/issues/1152 | MDEyOklzc3VlQ29tbWVudDc0ODIwNjg3NA== | simonw 9599 | 2020-12-18T17:03:00Z | 2020-12-22T23:58:04Z | OWNER | Another permissions thought: what if ALL Datasette permissions were default-deny, and plugins could only grant permission to things, not block permission? Right now a plugin can reply If everything in Datasette was default-deny then the user could use More importantly: plugins could return SQL statements that select a list of databases/tables the user is allowed access to. These could then be combined with |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Efficiently calculate list of databases/tables a user can view 770598024 | |
747920515 | https://github.com/simonw/datasette/issues/1152#issuecomment-747920515 | https://api.github.com/repos/simonw/datasette/issues/1152 | MDEyOklzc3VlQ29tbWVudDc0NzkyMDUxNQ== | simonw 9599 | 2020-12-18T07:29:21Z | 2020-12-22T23:57:29Z | OWNER | Could I solve this using a configured canned query against the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Efficiently calculate list of databases/tables a user can view 770598024 | |
749771231 | https://github.com/simonw/datasette/issues/1099#issuecomment-749771231 | https://api.github.com/repos/simonw/datasette/issues/1099 | MDEyOklzc3VlQ29tbWVudDc0OTc3MTIzMQ== | simonw 9599 | 2020-12-22T20:54:25Z | 2020-12-22T20:54:25Z | OWNER | https://latest.datasette.io/_internal/foreign_keys (use https://latest.datasette.io/login-as-root first) is now a compound foreign key table:
My original idea for compound foreign keys was to turn both of those columns into links, but that doesn't fit here because |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Support linking to compound foreign keys 743371103 | |
749750995 | https://github.com/simonw/datasette/issues/1152#issuecomment-749750995 | https://api.github.com/repos/simonw/datasette/issues/1152 | MDEyOklzc3VlQ29tbWVudDc0OTc1MDk5NQ== | simonw 9599 | 2020-12-22T20:05:30Z | 2020-12-22T20:05:30Z | OWNER | 1150 is landed now, which means there's a new, hidden |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Efficiently calculate list of databases/tables a user can view 770598024 | |
749749948 | https://github.com/simonw/datasette/issues/509#issuecomment-749749948 | https://api.github.com/repos/simonw/datasette/issues/509 | MDEyOklzc3VlQ29tbWVudDc0OTc0OTk0OA== | simonw 9599 | 2020-12-22T20:03:10Z | 2020-12-22T20:03:10Z | OWNER | If you open multiple files with the same filename, e.g. like this:
You'll now get this: |
{ "total_count": 1, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 1, "rocket": 0, "eyes": 0 } |
Support opening multiple databases with the same stem 456568880 | |
749738241 | https://github.com/simonw/datasette/issues/509#issuecomment-749738241 | https://api.github.com/repos/simonw/datasette/issues/509 | MDEyOklzc3VlQ29tbWVudDc0OTczODI0MQ== | simonw 9599 | 2020-12-22T19:38:14Z | 2020-12-22T19:38:14Z | OWNER | I'm fixing this in #1155. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Support opening multiple databases with the same stem 456568880 | |
749723557 | https://github.com/simonw/datasette/issues/1155#issuecomment-749723557 | https://api.github.com/repos/simonw/datasette/issues/1155 | MDEyOklzc3VlQ29tbWVudDc0OTcyMzU1Nw== | simonw 9599 | 2020-12-22T19:08:27Z | 2020-12-22T19:08:27Z | OWNER | I'm going to have the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Better internal database_name for _internal database 771216293 | |
748356492 | https://github.com/simonw/datasette/issues/1155#issuecomment-748356492 | https://api.github.com/repos/simonw/datasette/issues/1155 | MDEyOklzc3VlQ29tbWVudDc0ODM1NjQ5Mg== | simonw 9599 | 2020-12-18T22:49:32Z | 2020-12-22T01:13:05Z | OWNER | There's some messy code that needs fixing here. The While fixing this I should fix the issue where Datasette gets confused by multiple databases with the same stem: https://github.com/simonw/datasette/issues/509 |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Better internal database_name for _internal database 771216293 | |
749179460 | https://github.com/simonw/datasette/issues/1157#issuecomment-749179460 | https://api.github.com/repos/simonw/datasette/issues/1157 | MDEyOklzc3VlQ29tbWVudDc0OTE3OTQ2MA== | simonw 9599 | 2020-12-21T20:24:19Z | 2020-12-21T20:24:19Z | OWNER | Three places to fix: https://github.com/simonw/datasette/blob/dcdfb2c301341d45b66683e3e3be72f9c7585b2f/datasette/utils/init.py#L139-L152 |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Use time.perf_counter() instead of time.time() to measure performance 772438273 | |
749176936 | https://github.com/simonw/datasette/issues/1155#issuecomment-749176936 | https://api.github.com/repos/simonw/datasette/issues/1155 | MDEyOklzc3VlQ29tbWVudDc0OTE3NjkzNg== | simonw 9599 | 2020-12-21T20:18:15Z | 2020-12-21T20:18:15Z | OWNER | Fun query:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Better internal database_name for _internal database 771216293 | |
749170608 | https://github.com/simonw/datasette/issues/1155#issuecomment-749170608 | https://api.github.com/repos/simonw/datasette/issues/1155 | MDEyOklzc3VlQ29tbWVudDc0OTE3MDYwOA== | simonw 9599 | 2020-12-21T20:01:47Z | 2020-12-21T20:01:47Z | OWNER | I removed that |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Better internal database_name for _internal database 771216293 | |
749158111 | https://github.com/simonw/datasette/issues/1156#issuecomment-749158111 | https://api.github.com/repos/simonw/datasette/issues/1156 | MDEyOklzc3VlQ29tbWVudDc0OTE1ODExMQ== | simonw 9599 | 2020-12-21T19:33:45Z | 2020-12-21T19:33:45Z | OWNER | One reason for this change: it means I can use that database for more stuff. I've been thinking about moving metadata storage there for example, which fits a database called |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Rename _schemas to _internal 772408750 | |
748397998 | https://github.com/simonw/datasette/issues/1155#issuecomment-748397998 | https://api.github.com/repos/simonw/datasette/issues/1155 | MDEyOklzc3VlQ29tbWVudDc0ODM5Nzk5OA== | simonw 9599 | 2020-12-19T01:28:18Z | 2020-12-19T01:28:18Z | OWNER |
On the console:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Better internal database_name for _internal database 771216293 | |
748368660 | https://github.com/simonw/datasette/issues/1155#issuecomment-748368660 | https://api.github.com/repos/simonw/datasette/issues/1155 | MDEyOklzc3VlQ29tbWVudDc0ODM2ODY2MA== | simonw 9599 | 2020-12-18T23:18:04Z | 2020-12-19T01:12:00Z | OWNER | A |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Better internal database_name for _internal database 771216293 | |
748368938 | https://github.com/simonw/datasette/issues/1155#issuecomment-748368938 | https://api.github.com/repos/simonw/datasette/issues/1155 | MDEyOklzc3VlQ29tbWVudDc0ODM2ODkzOA== | simonw 9599 | 2020-12-18T23:19:04Z | 2020-12-18T23:19:04Z | OWNER |
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Better internal database_name for _internal database 771216293 | |
748368384 | https://github.com/simonw/datasette/issues/1155#issuecomment-748368384 | https://api.github.com/repos/simonw/datasette/issues/1155 | MDEyOklzc3VlQ29tbWVudDc0ODM2ODM4NA== | simonw 9599 | 2020-12-18T23:17:00Z | 2020-12-18T23:17:00Z | OWNER | Here's the commit where I added it. https://github.com/simonw/datasette/commit/9743e1d91b5f0a2b3c1c0bd6ffce8739341f43c4 - I didn't yet have the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Better internal database_name for _internal database 771216293 | |
748367922 | https://github.com/simonw/datasette/issues/1155#issuecomment-748367922 | https://api.github.com/repos/simonw/datasette/issues/1155 | MDEyOklzc3VlQ29tbWVudDc0ODM2NzkyMg== | simonw 9599 | 2020-12-18T23:15:24Z | 2020-12-18T23:15:24Z | OWNER | The code for building up that I'm not sure why I wrote it this way, instead of just calling |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Better internal database_name for _internal database 771216293 | |
748356637 | https://github.com/simonw/datasette/issues/509#issuecomment-748356637 | https://api.github.com/repos/simonw/datasette/issues/509 | MDEyOklzc3VlQ29tbWVudDc0ODM1NjYzNw== | simonw 9599 | 2020-12-18T22:50:03Z | 2020-12-18T22:50:03Z | OWNER | Related problem caused by the new |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Support opening multiple databases with the same stem 456568880 | |
748354841 | https://github.com/simonw/datasette/issues/1150#issuecomment-748354841 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0ODM1NDg0MQ== | simonw 9599 | 2020-12-18T22:43:49Z | 2020-12-18T22:43:49Z | OWNER | For a demo, visit https://latest.datasette.io/login-as-root and then hit https://latest.datasette.io/_schemas |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
748352106 | https://github.com/simonw/datasette/issues/1150#issuecomment-748352106 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0ODM1MjEwNg== | simonw 9599 | 2020-12-18T22:34:40Z | 2020-12-18T22:34:40Z | OWNER | Needs documentation, but I can wait to write that until I've tested out the feature a bit more. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
748351350 | https://github.com/simonw/datasette/issues/1150#issuecomment-748351350 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0ODM1MTM1MA== | simonw 9599 | 2020-12-18T22:32:13Z | 2020-12-18T22:32:13Z | OWNER | Getting all the tests to pass is tricky because this adds a whole extra database to Datasette - and there's various code that loops through |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
748260875 | https://github.com/simonw/datasette/issues/1150#issuecomment-748260875 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0ODI2MDg3NQ== | simonw 9599 | 2020-12-18T18:55:12Z | 2020-12-18T18:55:12Z | OWNER | I'm going to move the code into a |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
748260118 | https://github.com/simonw/datasette/issues/1150#issuecomment-748260118 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0ODI2MDExOA== | simonw 9599 | 2020-12-18T18:54:12Z | 2020-12-18T18:54:12Z | OWNER | I'm going to tidy this up and land it. A couple of additional decisions:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747966232 | https://github.com/simonw/datasette/issues/493#issuecomment-747966232 | https://api.github.com/repos/simonw/datasette/issues/493 | MDEyOklzc3VlQ29tbWVudDc0Nzk2NjIzMg== | simonw 9599 | 2020-12-18T09:19:41Z | 2020-12-18T09:19:41Z | OWNER | Is there any reason to keep |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Rename metadata.json to config.json 449886319 | |
747921195 | https://github.com/simonw/datasette/issues/1152#issuecomment-747921195 | https://api.github.com/repos/simonw/datasette/issues/1152 | MDEyOklzc3VlQ29tbWVudDc0NzkyMTE5NQ== | simonw 9599 | 2020-12-18T07:31:25Z | 2020-12-18T07:31:25Z | OWNER | It's also a really good fit for the new mechanism that's coming together in #1150. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Efficiently calculate list of databases/tables a user can view 770598024 | |
747920852 | https://github.com/simonw/datasette/issues/1152#issuecomment-747920852 | https://api.github.com/repos/simonw/datasette/issues/1152 | MDEyOklzc3VlQ29tbWVudDc0NzkyMDg1Mg== | simonw 9599 | 2020-12-18T07:30:22Z | 2020-12-18T07:30:22Z | OWNER | Redefining all Datasette permissions in terms of SQL queries that return the set of databases and tables that the user is allowed to interact with does feel VERY Datasette-y. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Efficiently calculate list of databases/tables a user can view 770598024 | |
747920087 | https://github.com/simonw/datasette/issues/1152#issuecomment-747920087 | https://api.github.com/repos/simonw/datasette/issues/1152 | MDEyOklzc3VlQ29tbWVudDc0NzkyMDA4Nw== | simonw 9599 | 2020-12-18T07:27:58Z | 2020-12-18T07:28:30Z | OWNER | I want to keep the existing |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Efficiently calculate list of databases/tables a user can view 770598024 | |
747919782 | https://github.com/simonw/datasette/issues/1152#issuecomment-747919782 | https://api.github.com/repos/simonw/datasette/issues/1152 | MDEyOklzc3VlQ29tbWVudDc0NzkxOTc4Mg== | simonw 9599 | 2020-12-18T07:27:01Z | 2020-12-18T07:27:01Z | OWNER | Perhaps this can be solved by keeping the existing plugin hooks and adding new, optional ones for bulk lookups. If your plugin doesn't implement the bulk lookup hooks Datasette will do an inefficient loop through everything checking permissions on each one. If you DO implement it you can speed things up dramatically. Not sure if this would solve the homepage problem though, where you might need to run 1,000 table permission checks. That's more a case where you want to think in terms of a SQL where clause. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Efficiently calculate list of databases/tables a user can view 770598024 | |
747893704 | https://github.com/simonw/datasette/issues/1150#issuecomment-747893704 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzg5MzcwNA== | simonw 9599 | 2020-12-18T06:19:13Z | 2020-12-18T06:19:13Z | OWNER | I'm not going to block this issue on permissions - I will tackle the efficient bulk permissions problem in #1152. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747893423 | https://github.com/simonw/datasette/issues/1152#issuecomment-747893423 | https://api.github.com/repos/simonw/datasette/issues/1152 | MDEyOklzc3VlQ29tbWVudDc0Nzg5MzQyMw== | simonw 9599 | 2020-12-18T06:18:24Z | 2020-12-18T06:18:24Z | OWNER | What would Datasette's permission hooks look like if they all dealt with sets of items rather than individual items? So plugins could return a set of items that the user has permission to access, or even a WHERE clause? |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Efficiently calculate list of databases/tables a user can view 770598024 | |
747892731 | https://github.com/simonw/datasette/issues/1152#issuecomment-747892731 | https://api.github.com/repos/simonw/datasette/issues/1152 | MDEyOklzc3VlQ29tbWVudDc0Nzg5MjczMQ== | simonw 9599 | 2020-12-18T06:16:29Z | 2020-12-18T06:16:29Z | OWNER | One enormous advantage I have is that after #1150 I will have a database table full of databases and tables that I can execute queries against. This means I could calculate visible tables using SQL where clauses, which should be easily fast enough even against ten thousand plus tables. The catch is the permissions hooks. Since I haven't hit Datasette 1.0 yet maybe I should redesign those hooks to work against the new in-memory database schema stuff? |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Efficiently calculate list of databases/tables a user can view 770598024 | |
747891854 | https://github.com/simonw/datasette/issues/1152#issuecomment-747891854 | https://api.github.com/repos/simonw/datasette/issues/1152 | MDEyOklzc3VlQ29tbWVudDc0Nzg5MTg1NA== | simonw 9599 | 2020-12-18T06:14:09Z | 2020-12-18T06:14:15Z | OWNER | This is a classic challenge in permissions systems. If I want Datasette to be able to handle thousands of tables I need a reasonable solution for it. Twitter conversation: https://twitter.com/simonw/status/1339791768842248192 |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Efficiently calculate list of databases/tables a user can view 770598024 | |
747864831 | https://github.com/simonw/datasette/issues/1150#issuecomment-747864831 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzg2NDgzMQ== | simonw 9599 | 2020-12-18T04:46:18Z | 2020-12-18T04:46:18Z | OWNER | The homepage currently performs a massive flurry of permission checks - one for each, database, table and view: https://github.com/simonw/datasette/blob/0.53/datasette/views/index.py#L21-L75 A paginated version of this is a little daunting as the permission checks would have to be carried out in every single table just to calculate the count that will be paginated. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747864080 | https://github.com/simonw/datasette/issues/1150#issuecomment-747864080 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzg2NDA4MA== | simonw 9599 | 2020-12-18T04:43:29Z | 2020-12-18T04:43:29Z | OWNER | I may be overthinking that problem. Many queries are fast in SQLite. If a Datasette instance has 1,000 connected tables will even that be a performance problem for permission checks? I should benchmark to find out. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747862001 | https://github.com/simonw/datasette/issues/1150#issuecomment-747862001 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzg2MjAwMQ== | simonw 9599 | 2020-12-18T04:35:34Z | 2020-12-18T04:35:34Z | OWNER | I do need to solve the permissions problem properly though, because one of the goals of this system is to provide a paginated, searchable list of databases and tables for the homepage of the instance - #991. As such, the homepage will need to be able to display only the tables and databases that the user has permission to view. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747861556 | https://github.com/simonw/datasette/issues/1150#issuecomment-747861556 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzg2MTU1Ng== | simonw 9599 | 2020-12-18T04:33:45Z | 2020-12-18T04:33:45Z | OWNER | One solution on permissions: if Datasette had an efficient way of saying "list the tables that this user has access to" I could use that as a filter any time the user views the schema information. The implementation could be tricky though. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747861357 | https://github.com/simonw/datasette/issues/1150#issuecomment-747861357 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzg2MTM1Nw== | simonw 9599 | 2020-12-18T04:32:52Z | 2020-12-18T04:32:52Z | OWNER | I need to figure out how this will interact with Datasette permissions. If some tables are private, but others are public, should users be able to see the private tables listed in the schema metadata? If not, how can that mechanism work? |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747833639 | https://github.com/simonw/datasette/issues/1150#issuecomment-747833639 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0NzgzMzYzOQ== | simonw 9599 | 2020-12-18T02:49:40Z | 2020-12-18T03:52:12Z | OWNER | I'm going to use five tables to start off with:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747847405 | https://github.com/simonw/datasette/issues/1150#issuecomment-747847405 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzg0NzQwNQ== | simonw 9599 | 2020-12-18T03:36:04Z | 2020-12-18T03:36:04Z | OWNER | I could have another table that stores the combined rows from |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747847180 | https://github.com/simonw/datasette/issues/1150#issuecomment-747847180 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzg0NzE4MA== | simonw 9599 | 2020-12-18T03:35:15Z | 2020-12-18T03:35:15Z | OWNER | Simpler implementation idea: a Datasette method |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747834762 | https://github.com/simonw/datasette/issues/1150#issuecomment-747834762 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0NzgzNDc2Mg== | simonw 9599 | 2020-12-18T02:53:22Z | 2020-12-18T02:53:22Z | OWNER | I think I'm going to have to build this without using the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747834462 | https://github.com/simonw/datasette/issues/1150#issuecomment-747834462 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0NzgzNDQ2Mg== | simonw 9599 | 2020-12-18T02:52:19Z | 2020-12-18T02:52:26Z | OWNER | Maintaining this database will be the responsibility of a subclass of |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747834113 | https://github.com/simonw/datasette/issues/1150#issuecomment-747834113 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0NzgzNDExMw== | simonw 9599 | 2020-12-18T02:51:13Z | 2020-12-18T02:51:20Z | OWNER | SQLite uses |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747809670 | https://github.com/simonw/datasette/issues/1150#issuecomment-747809670 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0NzgwOTY3MA== | simonw 9599 | 2020-12-18T01:29:30Z | 2020-12-18T01:29:30Z | OWNER | I've been rediscovering the pattern I already documented in this TIL: https://github.com/simonw/til/blob/main/sqlite/list-all-columns-in-a-database.md#better-alternative-using-a-join |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747807891 | https://github.com/simonw/datasette/issues/1150#issuecomment-747807891 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0NzgwNzg5MQ== | simonw 9599 | 2020-12-18T01:23:59Z | 2020-12-18T01:23:59Z | OWNER | https://www.sqlite.org/pragma.html#pragfunc says:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747807289 | https://github.com/simonw/datasette/issues/1150#issuecomment-747807289 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0NzgwNzI4OQ== | simonw 9599 | 2020-12-18T01:22:05Z | 2020-12-18T01:22:05Z | OWNER | Here's a simpler query pattern (not using CTEs so should work on older versions of SQLite) - this one lists all indexes for all tables:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747805275 | https://github.com/simonw/datasette/issues/1150#issuecomment-747805275 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0NzgwNTI3NQ== | simonw 9599 | 2020-12-18T01:15:27Z | 2020-12-18T01:16:17Z | OWNER | This query uses a join to pull foreign key information for every table: https://latest.datasette.io/fixtures?sql=with+tables+as+%28%0D%0A++select%0D%0A++++name%0D%0A++from%0D%0A++++sqlite_master%0D%0A++where%0D%0A++++type+%3D+%27table%27%0D%0A%29%0D%0Aselect%0D%0A++tables.name+as+%27table%27%2C%0D%0A++foo.*%0D%0Afrom%0D%0A++tables%0D%0A++join+pragma_foreign_key_list%28tables.name%29+foo
Same query for |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747804254 | https://github.com/simonw/datasette/issues/1150#issuecomment-747804254 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0NzgwNDI1NA== | simonw 9599 | 2020-12-18T01:12:13Z | 2020-12-18T01:12:13Z | OWNER | Prototype: https://latest.datasette.io/fixtures?sql=select+%27facetable%27+as+%27table%27%2C++from+pragma_table_xinfo%28%27facetable%27%29%0D%0Aunion%0D%0Aselect+%27searchable%27+as+%27table%27%2C++from+pragma_table_xinfo%28%27searchable%27%29%0D%0Aunion%0D%0Aselect+%27compound_three_primary_keys%27+as+%27table%27%2C+*+from+pragma_table_xinfo%28%27compound_three_primary_keys%27%29
table | cid | name | type | notnull | dflt_value | pk | hidden -- | -- | -- | -- | -- | -- | -- | -- compound_three_primary_keys | 0 | pk1 | varchar(30) | 0 | | 1 | 0 compound_three_primary_keys | 1 | pk2 | varchar(30) | 0 | | 2 | 0 compound_three_primary_keys | 2 | pk3 | varchar(30) | 0 | | 3 | 0 compound_three_primary_keys | 3 | content | text | 0 | | 0 | 0 facetable | 0 | pk | integer | 0 | | 1 | 0 facetable | 1 | created | text | 0 | | 0 | 0 facetable | 2 | planet_int | integer | 0 | | 0 | 0 facetable | 3 | on_earth | integer | 0 | | 0 | 0 facetable | 4 | state | text | 0 | | 0 | 0 facetable | 5 | city_id | integer | 0 | | 0 | 0 facetable | 6 | neighborhood | text | 0 | | 0 | 0 facetable | 7 | tags | text | 0 | | 0 | 0 facetable | 8 | complex_array | text | 0 | | 0 | 0 facetable | 9 | distinct_some_null | | 0 | | 0 | 0 searchable | 0 | pk | integer | 0 | | 1 | 0 searchable | 1 | text1 | text | 0 | | 0 | 0 searchable | 2 | text2 | text | 0 | | 0 | 0 searchable | 3 | name with . and spaces | text | 0 | | 0 | 0 |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747803268 | https://github.com/simonw/datasette/issues/1150#issuecomment-747803268 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0NzgwMzI2OA== | simonw 9599 | 2020-12-18T01:08:40Z | 2020-12-18T01:08:40Z | OWNER | Next step: design a schema for the in-memory database table that exposes all of the tables. I want to support things like:
Maybe a starting point would be to build concrete tables using the results of things like |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747801751 | https://github.com/simonw/datasette/issues/1151#issuecomment-747801751 | https://api.github.com/repos/simonw/datasette/issues/1151 | MDEyOklzc3VlQ29tbWVudDc0NzgwMTc1MQ== | simonw 9599 | 2020-12-18T01:03:39Z | 2020-12-18T01:03:39Z | OWNER | This feature is illustrated by the tests: https://github.com/simonw/datasette/blob/5e9895c67f08e9f42acedd3d6d29512ac446e15f/tests/test_internals_database.py#L469-L496 I added new documentation for the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Database class mechanism for cross-connection in-memory databases 770448622 | |
747801084 | https://github.com/simonw/datasette/issues/1151#issuecomment-747801084 | https://api.github.com/repos/simonw/datasette/issues/1151 | MDEyOklzc3VlQ29tbWVudDc0NzgwMTA4NA== | simonw 9599 | 2020-12-18T01:01:26Z | 2020-12-18T01:01:26Z | OWNER | I tested this with a one-off plugin and it worked! ```python from datasette import hookimpl from datasette.database import Database @hookimpl
def startup(datasette):
datasette.add_database("statistics", Database(
datasette,
memory_name="statistics"
))
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Database class mechanism for cross-connection in-memory databases 770448622 | |
747784199 | https://github.com/simonw/datasette/issues/1151#issuecomment-747784199 | https://api.github.com/repos/simonw/datasette/issues/1151 | MDEyOklzc3VlQ29tbWVudDc0Nzc4NDE5OQ== | simonw 9599 | 2020-12-18T00:09:36Z | 2020-12-18T00:09:36Z | OWNER | Is it possible to connect to a memory database in read-only mode?
https://stackoverflow.com/a/40548682 suggests using |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Database class mechanism for cross-connection in-memory databases 770448622 | |
747775245 | https://github.com/simonw/datasette/issues/1151#issuecomment-747775245 | https://api.github.com/repos/simonw/datasette/issues/1151 | MDEyOklzc3VlQ29tbWVudDc0Nzc3NTI0NQ== | simonw 9599 | 2020-12-17T23:43:41Z | 2020-12-17T23:56:27Z | OWNER | I'm going to add an argument to the
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Database class mechanism for cross-connection in-memory databases 770448622 | |
747779056 | https://github.com/simonw/datasette/issues/1151#issuecomment-747779056 | https://api.github.com/repos/simonw/datasette/issues/1151 | MDEyOklzc3VlQ29tbWVudDc0Nzc3OTA1Ng== | simonw 9599 | 2020-12-17T23:55:57Z | 2020-12-17T23:55:57Z | OWNER | Wait I do use it - if you run |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Database class mechanism for cross-connection in-memory databases 770448622 | |
747775792 | https://github.com/simonw/datasette/issues/1151#issuecomment-747775792 | https://api.github.com/repos/simonw/datasette/issues/1151 | MDEyOklzc3VlQ29tbWVudDc0Nzc3NTc5Mg== | simonw 9599 | 2020-12-17T23:45:20Z | 2020-12-17T23:45:20Z | OWNER | Do I use the current https://ripgrep.datasette.io/-/ripgrep?pattern=is_memory - doesn't look like it. I may remove that feature, since it's not actually useful, and replace it with a mechanism for creating shared named memory databases instead. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Database class mechanism for cross-connection in-memory databases 770448622 | |
747774855 | https://github.com/simonw/datasette/issues/1151#issuecomment-747774855 | https://api.github.com/repos/simonw/datasette/issues/1151 | MDEyOklzc3VlQ29tbWVudDc0Nzc3NDg1NQ== | simonw 9599 | 2020-12-17T23:42:34Z | 2020-12-17T23:42:34Z | OWNER | This worked as a prototype: ```diff diff --git a/datasette/database.py b/datasette/database.py index 412e0c5..a90e617 100644 --- a/datasette/database.py +++ b/datasette/database.py @@ -24,11 +24,12 @@ connections = threading.local() class Database: - def init(self, ds, path=None, is_mutable=False, is_memory=False): + def init(self, ds, path=None, is_mutable=False, is_memory=False, uri=None): self.ds = ds self.path = path self.is_mutable = is_mutable self.is_memory = is_memory + self.uri = uri self.hash = None self.cached_size = None self.cached_table_counts = None @@ -46,6 +47,8 @@ class Database: }
Outputs ["foo"]db2 = Database(ds, uri="file:datasette?mode=memory&cache=shared", is_memory=True) await db2.table_names() Also outputs ["foo"]``` ``` |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Database class mechanism for cross-connection in-memory databases 770448622 | |
747770581 | https://github.com/simonw/datasette/issues/1151#issuecomment-747770581 | https://api.github.com/repos/simonw/datasette/issues/1151 | MDEyOklzc3VlQ29tbWVudDc0Nzc3MDU4MQ== | simonw 9599 | 2020-12-17T23:31:18Z | 2020-12-17T23:32:07Z | OWNER | This works in In [2]: c1 = sqlite3.connect("file:datasette?mode=memory&cache=shared", uri=True) In [3]: c2 = sqlite3.connect("file:datasette?mode=memory&cache=shared", uri=True) In [4]: c1.executescript("CREATE TABLE hello (world TEXT)") Out[4]: <sqlite3.Cursor at 0x1104addc0> In [5]: c1.execute("select * from sqlite_master").fetchall() Out[5]: [('table', 'hello', 'hello', 2, 'CREATE TABLE hello (world TEXT)')] In [6]: c2.execute("select * from sqlite_master").fetchall() Out[6]: [('table', 'hello', 'hello', 2, 'CREATE TABLE hello (world TEXT)')] In [7]: c3 = sqlite3.connect("file:datasette?mode=memory&cache=shared", uri=True) In [9]: c3.execute("select * from sqlite_master").fetchall() Out[9]: [('table', 'hello', 'hello', 2, 'CREATE TABLE hello (world TEXT)')] In [10]: c4 = sqlite3.connect("file:datasette?mode=memory", uri=True) In [11]: c4.execute("select * from sqlite_master").fetchall() Out[11]: [] ``` |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Database class mechanism for cross-connection in-memory databases 770448622 | |
747770082 | https://github.com/simonw/datasette/issues/1151#issuecomment-747770082 | https://api.github.com/repos/simonw/datasette/issues/1151 | MDEyOklzc3VlQ29tbWVudDc0Nzc3MDA4Mg== | simonw 9599 | 2020-12-17T23:29:53Z | 2020-12-17T23:29:53Z | OWNER | I'm going to try with |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Database class mechanism for cross-connection in-memory databases 770448622 | |
747769830 | https://github.com/simonw/datasette/issues/1151#issuecomment-747769830 | https://api.github.com/repos/simonw/datasette/issues/1151 | MDEyOklzc3VlQ29tbWVudDc0Nzc2OTgzMA== | simonw 9599 | 2020-12-17T23:29:08Z | 2020-12-17T23:29:08Z | OWNER | https://sqlite.org/inmemorydb.html
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Database class mechanism for cross-connection in-memory databases 770448622 | |
747768112 | https://github.com/simonw/datasette/issues/1150#issuecomment-747768112 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzc2ODExMg== | simonw 9599 | 2020-12-17T23:25:21Z | 2020-12-17T23:25:21Z | OWNER | Next challenge: figure out how to use the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747767598 | https://github.com/simonw/datasette/issues/1150#issuecomment-747767598 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzc2NzU5OA== | simonw 9599 | 2020-12-17T23:24:03Z | 2020-12-17T23:24:03Z | OWNER | I'm going to assume that even the heaviest user will have trouble going beyond a few hundred database files, so this is fine. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747767499 | https://github.com/simonw/datasette/issues/1150#issuecomment-747767499 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzc2NzQ5OQ== | simonw 9599 | 2020-12-17T23:23:44Z | 2020-12-17T23:23:44Z | OWNER | Grabbing the schema version of 380 files in the root directory takes 70ms. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747767055 | https://github.com/simonw/datasette/issues/1150#issuecomment-747767055 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzc2NzA1NQ== | simonw 9599 | 2020-12-17T23:22:41Z | 2020-12-17T23:22:41Z | OWNER | It's just recursion that's expensive. I created 380 empty SQLite databases in a folder and timed So maybe I tell users that all SQLite databases have to be in the root folder. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747766310 | https://github.com/simonw/datasette/issues/1150#issuecomment-747766310 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzc2NjMxMA== | simonw 9599 | 2020-12-17T23:20:49Z | 2020-12-17T23:20:49Z | OWNER | I tried against my entire So it looks like connecting to a SQLite database file and getting the schema version is extremely fast. Scanning directories is slower. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747764712 | https://github.com/simonw/datasette/issues/1150#issuecomment-747764712 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzc2NDcxMg== | simonw 9599 | 2020-12-17T23:16:31Z | 2020-12-17T23:16:31Z | OWNER | Quick micro-benchmark, run against a folder with 46 database files adding up to 1.4GB total: ```python import pathlib, sqlite3, time paths = list(pathlib.Path(".").glob('*.db')) def schema_version(path): db = sqlite3.connect(path) version = db.execute("PRAGMA schema_version").fetchall()[0] db.close() return version def all(): versions = {} for path in paths: versions[path.name] = schema_version(path) return versions start = time.time(); all(); print(time.time() - start) 0.012346982955932617``` So that's 12ms. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747754229 | https://github.com/simonw/datasette/issues/1150#issuecomment-747754229 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzc1NDIyOQ== | simonw 9599 | 2020-12-17T23:04:38Z | 2020-12-17T23:04:38Z | OWNER | Open question: will this work for hundreds of database files, or is the overhead of connecting to each of 100 databases in turn to run |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747754082 | https://github.com/simonw/datasette/issues/1150#issuecomment-747754082 | https://api.github.com/repos/simonw/datasette/issues/1150 | MDEyOklzc3VlQ29tbWVudDc0Nzc1NDA4Mg== | simonw 9599 | 2020-12-17T23:04:13Z | 2020-12-17T23:04:13Z | OWNER | Pages that need a list of all databases - the index page and /-/databases for example - could trigger a "check for new directories in the configured directories" scan. That scan would run at most once every 5 (n) seconds - the check is triggered if it’s run more recently than that it doesn’t run. Hopefully this means it could be done as a blocking operation, rather than trying to run it in a thread. When it runs it scans for .db or .sqlite files (maybe one or two other extensions) that it hasn’t seen before. It also checks that the existing list of known database files still exists. If it finds any new ones it connects to them once to run |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Maintain an in-memory SQLite table of connected databases and their tables 770436876 | |
747734273 | https://github.com/simonw/datasette/issues/461#issuecomment-747734273 | https://api.github.com/repos/simonw/datasette/issues/461 | MDEyOklzc3VlQ29tbWVudDc0NzczNDI3Mw== | simonw 9599 | 2020-12-17T22:14:46Z | 2020-12-17T22:14:46Z | OWNER | I've been thinking about this a bunch. For Datasette to be useful as a private repository of data (Datasette Library, #417) it's crucial that it can handle a much, much larger number of databases. This makes me worry about how many connections (and open file handles) it makes sense to have open at one time. I realize now that this is much less of a problem for private instances. Public instances on the internet could get traffic to any database at any time, so connections could easily get out of control. A private instance with only a few users could instead get away with only opening connections to databases in "active use". This does however make it even more important for Datasette to maintain a cached set of metadata about the tables - which is also needed to power this feature. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Paginate + search for databases/tables on the homepage 443021509 | |
747209115 | https://github.com/simonw/datasette/issues/1005#issuecomment-747209115 | https://api.github.com/repos/simonw/datasette/issues/1005 | MDEyOklzc3VlQ29tbWVudDc0NzIwOTExNQ== | simonw 9599 | 2020-12-17T05:11:04Z | 2020-12-17T05:11:04Z | OWNER | Tracking ticket for the next HTTPX release is https://github.com/encode/httpx/pull/1403 |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Remove xfail tests when new httpx is released 718259202 | |
747208543 | https://github.com/simonw/datasette/issues/741#issuecomment-747208543 | https://api.github.com/repos/simonw/datasette/issues/741 | MDEyOklzc3VlQ29tbWVudDc0NzIwODU0Mw== | simonw 9599 | 2020-12-17T05:09:03Z | 2020-12-17T05:09:03Z | OWNER | I really like this in |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Replace "datasette publish --extra-options" with "--setting" 607223136 | |
747207787 | https://github.com/simonw/datasette/issues/1149#issuecomment-747207787 | https://api.github.com/repos/simonw/datasette/issues/1149 | MDEyOklzc3VlQ29tbWVudDc0NzIwNzc4Nw== | simonw 9599 | 2020-12-17T05:06:16Z | 2020-12-17T05:06:16Z | OWNER | So, an idea: what if Datasette's default CSS applied only to elements with classes - or maybe to childen of a |
{ "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make it easier to theme Datasette with CSS 769520939 |
Advanced export
JSON shape: default, array, newline-delimited, object
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]);
issue >30