{"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-753568428", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 753568428, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MzU2ODQyOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-01-03T05:02:32Z", "updated_at": "2021-01-03T05:02:32Z", "author_association": "OWNER", "body": "Should this command include a `--fts` option for configuring full-text search on one-or-more columns?\r\n\r\nI thought about doing that for `sqlite-utils insert` in https://github.com/simonw/sqlite-utils/issues/202 and decided not to because of the need to include extra options covering the FTS version, porter stemming options and whether or not to create triggers.\r\n\r\nBut maybe I can set sensible defaults for that with `datasette insert ... -f title -f body`? Worth thinking about a bit more.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-752275611", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 752275611, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MjI3NTYxMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T23:32:04Z", "updated_at": "2020-12-29T23:32:04Z", "author_association": "OWNER", "body": "If I can get this working for CSV, TSV, JSON and JSON-NL that should be enough to exercise the API design pretty well across both streaming and non-streaming formats.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-752274509", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 752274509, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MjI3NDUwOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T23:26:02Z", "updated_at": "2020-12-29T23:26:02Z", "author_association": "OWNER", "body": "The documentation for this plugin hook is going to be pretty detailed, since it involves writing custom classes.\r\n\r\nI'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.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-752274078", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 752274078, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MjI3NDA3OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T23:23:39Z", "updated_at": "2020-12-29T23:23:39Z", "author_association": "OWNER", "body": "If I design this right I can ship a full version of the command-line `datasette insert` command in a release without doing any work at all on the Web UI version of it - that UI can then come later, without needing any changes to be made to the plugin hook.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-752273873", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 752273873, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MjI3Mzg3Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T23:22:30Z", "updated_at": "2020-12-29T23:22:30Z", "author_association": "OWNER", "body": "How much of this should I get done in a branch before merging into `main`?\r\n\r\nThe challenge here is the plugin hook design: ideally I don't want an incomplete plugin hook design in `main` since that could be a blocker for a release.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-752273400", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 752273400, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MjI3MzQwMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T23:19:46Z", "updated_at": "2020-12-29T23:19:46Z", "author_association": "OWNER", "body": "I'm going to break out some separate tickets.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-752273306", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 752273306, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MjI3MzMwNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T23:19:15Z", "updated_at": "2020-12-29T23:19:15Z", "author_association": "OWNER", "body": "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 `content-length` HTTP header is missing) - but if they ARE possible it would be good to provide them - both for the CLI interface and the web insert UI.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-752267905", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 752267905, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MjI2NzkwNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T22:52:09Z", "updated_at": "2020-12-29T22:52:09Z", "author_association": "OWNER", "body": "What's the simplest thing that could possible work? I think it's `datasette insert blah.db data.csv` - no URL handling, no other formats.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-752266076", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 752266076, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MjI2NjA3Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T22:42:23Z", "updated_at": "2020-12-29T22:42:59Z", "author_association": "OWNER", "body": "Aside: maybe `datasette insert` works against simple files, but a later mechanism called `datasette import` allows plugins to register sub-commands, like `datasette import github ...` or `datasette import jira ...` or whatever.\r\n\r\nThis would be useful for import mechanisms that are likely to need their own custom set of command-line options unique to that source.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-752265600", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 752265600, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MjI2NTYwMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T22:39:56Z", "updated_at": "2020-12-29T22:39:56Z", "author_association": "OWNER", "body": "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 `sqlite-utils`?\r\n\r\nThat 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?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-752259345", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 752259345, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MjI1OTM0NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T22:11:54Z", "updated_at": "2020-12-29T22:11:54Z", "author_association": "OWNER", "body": "Important detail from https://docs.python.org/3/library/csv.html#csv.reader\r\n\r\n> If *csvfile* is a file object, it should be opened with `newline=''`. [1]\r\n>\r\n> [...]\r\n>\r\n> If `newline=''` is not specified, newlines embedded inside quoted fields will not be interpreted correctly, and on platforms that use `\\r\\n` linendings on write an extra `\\r` will be added. It should always be safe to specify `newline=''`, since the csv module does its own ([universal](https://docs.python.org/3/glossary.html#term-universal-newlines)) newline handling.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-752257666", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 752257666, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MjI1NzY2Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T22:09:18Z", "updated_at": "2020-12-29T22:09:18Z", "author_association": "OWNER", "body": "### Figuring out the API design\r\n\r\nI 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.\r\n\r\nIdeally 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.\r\n\r\nCSV is easy to parse as a stream - here\u2019s [how sqlite-utils does it](https://github.com/simonw/sqlite-utils/blob/f1277f638f3a54a821db6e03cb980adad2f2fa35/sqlite_utils/cli.py#L630):\r\n\r\n dialect = \"excel-tab\" if tsv else \"excel\"\r\n with file_progress(json_file, silent=silent) as json_file:\r\n reader = csv_std.reader(json_file, dialect=dialect)\r\n headers = next(reader)\r\n docs = (dict(zip(headers, row)) for row in reader)\r\n\r\nProblem: using `db.insert_all()` could block for a long time on a big set of rows. Probably easiest to batch the records before calling `insert_all()` and then run a batch at a time using a `db.execute_write_fn()` call.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-752236520", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 752236520, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MjIzNjUyMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T20:48:51Z", "updated_at": "2020-12-29T20:48:51Z", "author_association": "OWNER", "body": "It would be neat if `datasette insert` could accept a `--plugins-dir` option which allowed one-off format plugins to be registered. Bit tricky to implement since the `--format` Click option will already be populated by that plugin hook call.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-751925934", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 751925934, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MTkyNTkzNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T02:40:13Z", "updated_at": "2020-12-29T20:25:57Z", "author_association": "OWNER", "body": "Basic command design:\r\n\r\n datasette insert data.db blah.csv\r\n\r\nThe options can include:\r\n\r\n- `--format` to specify the exact format - without this it will be guessed based on the filename\r\n- `--table` to specify the table (otherwise the filename is used)\r\n- `--pk` to specify one or more primary key columns\r\n- `--replace` to specify that existing rows with a matching primary key should be replaced\r\n- `--upsert` to specify that existing matching rows should be upserted\r\n- `--ignore` to ignore matching rows\r\n- `--alter` to alter the table to add missing columns\r\n- `--type column type` to specify the type of a column - useful when working with CSV or TSV files", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-752208036", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 752208036, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MjIwODAzNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T19:06:35Z", "updated_at": "2020-12-29T19:06:35Z", "author_association": "OWNER", "body": "If I'm going to execute 1000s of writes in an `async def` operation it may make sense to break that up into smaller chunks, so as not to block the event loop for too long.\r\n\r\nhttps://stackoverflow.com/a/36648102 and https://github.com/python/asyncio/issues/284 confirm that `await asyncio.sleep(0)` is the recommended way of doing this.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-752203909", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 752203909, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MjIwMzkwOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T18:54:19Z", "updated_at": "2020-12-29T18:54:19Z", "author_association": "OWNER", "body": "More thoughts on this: the key mechanism that populates the tables needs to be an `aysnc def` method of some sort so that it can run as part of the async loop in core Datasette - for importing from web uploads.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-751947991", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 751947991, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MTk0Nzk5MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T05:06:50Z", "updated_at": "2020-12-29T05:07:03Z", "author_association": "OWNER", "body": "Given the URL option could it be possible for plugins to \"subscribe\" to URLs that keep on streaming?\r\n\r\n datasette insert db.db https://example.con/streaming-api \\\r\n --format api-stream", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-751946262", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 751946262, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MTk0NjI2Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T04:56:12Z", "updated_at": "2020-12-29T04:56:32Z", "author_association": "OWNER", "body": "Potential design for this: a `datasette memory` command which takes most of the same arguments as `datasette serve` but starts an in-memory database and treats the command arguments as things that should be inserted into that in-memory database.\r\n\r\n tail -f access.log | datasette memory - \\\r\n --format clf -p 8002 -o", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-751945094", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 751945094, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MTk0NTA5NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T04:48:11Z", "updated_at": "2020-12-29T04:48:11Z", "author_association": "OWNER", "body": "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.\r\n\r\nOr 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...\r\n\r\nNot quite sure what that CLI interface would look like. Maybe treat that as a future stretch goal for the moment.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-751943837", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 751943837, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MTk0MzgzNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T04:40:30Z", "updated_at": "2020-12-29T04:40:30Z", "author_association": "OWNER", "body": "The `insert` command should also accept URLs - anything starting with `http://` or `https://`.\r\n\r\nIt should accept more than one file name at a time for bulk inserts.\r\n\r\nif 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.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-751926437", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 751926437, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MTkyNjQzNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T02:43:21Z", "updated_at": "2020-12-29T02:43:37Z", "author_association": "OWNER", "body": "Default formats to support:\r\n\r\n- CSV\r\n- TSV\r\n- JSON and newline-delimited JSON\r\n- YAML\r\n\r\nEach of these will be implemented as a default plugin.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-751926218", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 751926218, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MTkyNjIxOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T02:41:57Z", "updated_at": "2020-12-29T02:41:57Z", "author_association": "OWNER", "body": "Other names I considered:\r\n\r\n- `datasette load`\r\n- `datasette import` - I decided to keep this name available for any future work that might involve plugins that help import data from APIs as opposed to inserting it from files", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1160#issuecomment-751926095", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1160", "id": 751926095, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MTkyNjA5NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-29T02:41:15Z", "updated_at": "2020-12-29T02:41:15Z", "author_association": "OWNER", "body": "The UI can live at `/-/insert` and be available by default to the `root` user only. It can offer the following:\r\n\r\n- Upload a file and have the import type detected (equivalent to `datasette insert data.db thatfile.csv`)\r\n- Copy and paste the data to be inserted into a textarea\r\n- API equivalents of these", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 775666296, "label": "\"datasette insert\" command and plugin hook"}, "performed_via_github_app": null}