html_url,issue_url,id,node_id,user,user_label,created_at,updated_at,author_association,body,reactions,issue,issue_label,performed_via_github_app https://github.com/simonw/sqlite-utils/issues/574#issuecomment-1646688748,https://api.github.com/repos/simonw/sqlite-utils/issues/574,1646688748,IC_kwDOCGYnMM5iJnns,9599,simonw,2023-07-22T23:12:03Z,2023-07-22T23:13:14Z,OWNER,"Just tried this out by adding the example from the docs to my `sqlite-utils-hello-world` plugin and running: ```bash sqlite-utils install -e ../sqlite-utils-hello-world ``` ``` Obtaining file:///Users/simon/Dropbox/Development/sqlite-utils-hello-world ... ``` Then: ```bash sqlite-utils memory ""select hello('simon')"" ``` ```json [{""hello('simon')"": ""Hello, simon!""}] ``` Also: ```pycon >>> import sqlite_utils >>> db = sqlite_utils.Database(memory=True) >>> list(db.query(""select hello('simon')"")) [{""hello('simon')"": 'Hello, simon!'}] >>> db2 = sqlite_utils.Database(memory=True, execute_plugins=False) >>> list(db2.query(""select hello('simon')"")) Traceback (most recent call last): File """", line 1, in File ""/Users/simon/Dropbox/Development/sqlite-utils/sqlite_utils/db.py"", line 494, in query cursor = self.execute(sql, params or tuple()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File ""/Users/simon/Dropbox/Development/sqlite-utils/sqlite_utils/db.py"", line 512, in execute return self.conn.execute(sql, parameters) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ sqlean.dbapi2.OperationalError: no such function: hello ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816918185,`prepare_connection()` plugin hook, https://github.com/simonw/sqlite-utils/issues/574#issuecomment-1646688339,https://api.github.com/repos/simonw/sqlite-utils/issues/574,1646688339,IC_kwDOCGYnMM5iJnhT,9599,simonw,2023-07-22T23:08:49Z,2023-07-22T23:08:49Z,OWNER,Documentation: https://sqlite-utils.datasette.io/en/latest/plugins.html#prepare-connection-conn,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816918185,`prepare_connection()` plugin hook, https://github.com/simonw/sqlite-utils/issues/575#issuecomment-1646688288,https://api.github.com/repos/simonw/sqlite-utils/issues/575,1646688288,IC_kwDOCGYnMM5iJngg,9599,simonw,2023-07-22T23:08:22Z,2023-07-22T23:08:22Z,OWNER,Documented here: https://sqlite-utils.datasette.io/en/latest/plugins.html,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816919568,Python API ability to opt-out of connection plugins, https://github.com/simonw/sqlite-utils/issues/575#issuecomment-1646687461,https://api.github.com/repos/simonw/sqlite-utils/issues/575,1646687461,IC_kwDOCGYnMM5iJnTl,9599,simonw,2023-07-22T23:01:44Z,2023-07-22T23:01:44Z,OWNER,Relevant code: https://github.com/simonw/sqlite-utils/blob/3f80a026983d3e634f05a46f2a6da162b5139dd9/sqlite_utils/db.py#L346,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816919568,Python API ability to opt-out of connection plugins, https://github.com/simonw/sqlite-utils/issues/567#issuecomment-1646687219,https://api.github.com/repos/simonw/sqlite-utils/issues/567,1646687219,IC_kwDOCGYnMM5iJnPz,9599,simonw,2023-07-22T22:59:36Z,2023-07-22T22:59:36Z,OWNER,Now that we have two plugin hooks I'm closing this issue (we can open other issues for further hooks).,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1801394744,Plugin system, https://github.com/simonw/sqlite-utils/pull/573#issuecomment-1646687103,https://api.github.com/repos/simonw/sqlite-utils/issues/573,1646687103,IC_kwDOCGYnMM5iJnN_,9599,simonw,2023-07-22T22:58:35Z,2023-07-22T22:58:35Z,OWNER,"https://sqlite-utils--573.org.readthedocs.build/en/573/plugins.html#prepare-connection-conn ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816917522,feat: Implement a prepare_connection plugin hook, https://github.com/simonw/sqlite-utils/pull/573#issuecomment-1646686675,https://api.github.com/repos/simonw/sqlite-utils/issues/573,1646686675,IC_kwDOCGYnMM5iJnHT,9599,simonw,2023-07-22T22:54:38Z,2023-07-22T22:54:38Z,OWNER," Glitch in the rendered documentation from https://sqlite-utils--573.org.readthedocs.build/en/573/plugins.html#prepare-connection-conn","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816917522,feat: Implement a prepare_connection plugin hook, https://github.com/simonw/sqlite-utils/issues/574#issuecomment-1646686477,https://api.github.com/repos/simonw/sqlite-utils/issues/574,1646686477,IC_kwDOCGYnMM5iJnEN,9599,simonw,2023-07-22T22:52:56Z,2023-07-22T22:52:56Z,OWNER,"Alex built this in: - #573","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816918185,`prepare_connection()` plugin hook, https://github.com/simonw/sqlite-utils/issues/567#issuecomment-1646686424,https://api.github.com/repos/simonw/sqlite-utils/issues/567,1646686424,IC_kwDOCGYnMM5iJnDY,9599,simonw,2023-07-22T22:52:34Z,2023-07-22T22:52:34Z,OWNER,Splitting off an issue for `prepare_connection()` since Alex got the PR in seconds before I shipped 3.34!,"{""total_count"": 1, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 1, ""rocket"": 0, ""eyes"": 0}",1801394744,Plugin system, https://github.com/simonw/sqlite-utils/pull/573#issuecomment-1646686332,https://api.github.com/repos/simonw/sqlite-utils/issues/573,1646686332,IC_kwDOCGYnMM5iJnB8,9599,simonw,2023-07-22T22:52:01Z,2023-07-22T22:52:01Z,OWNER,I was literally seconds away from shipping version 3.34 but I this looks good so I'm going to try and get it in there.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816917522,feat: Implement a prepare_connection plugin hook, https://github.com/simonw/sqlite-utils/issues/571#issuecomment-1646682686,https://api.github.com/repos/simonw/sqlite-utils/issues/571,1646682686,IC_kwDOCGYnMM5iJmI-,9599,simonw,2023-07-22T22:23:47Z,2023-07-22T22:23:47Z,OWNER,"Demo: ```pycon >>> from sqlite_utils import Database >>> db = Database(memory=True) >>> db[""foo""].insert({""name"": ""Cleo""}) >>> print(db[""foo""].schema) CREATE TABLE [foo] ( [name] TEXT ) >>> db[""foo""].transform(not_null={""name""})
>>> print(db[""foo""].schema) CREATE TABLE ""foo"" ( [name] TEXT NOT NULL ) >>> db[""foo""].transform(types={""name"": int}, keep_table=""kept"")
>>> print(db.schema) CREATE TABLE ""kept"" ( [name] TEXT NOT NULL ); CREATE TABLE ""foo"" ( [name] INTEGER NOT NULL ); ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816876211,`.transform(keep_table=...)` option, https://github.com/simonw/sqlite-utils/issues/426#issuecomment-1646681386,https://api.github.com/repos/simonw/sqlite-utils/issues/426,1646681386,IC_kwDOCGYnMM5iJl0q,9599,simonw,2023-07-22T22:13:22Z,2023-07-22T22:13:22Z,OWNER,I'm happy with how this works on https://sqlite-utils.datasette.io/en/stable/cli-reference.html,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1205687423,CLI docs should link to Python docs and vice versa, https://github.com/simonw/sqlite-utils/issues/572#issuecomment-1646681192,https://api.github.com/repos/simonw/sqlite-utils/issues/572,1646681192,IC_kwDOCGYnMM5iJlxo,9599,simonw,2023-07-22T22:12:08Z,2023-07-22T22:12:08Z,OWNER,Found it: https://github.com/simonw/sqlite-utils/blob/18f190e28334d821be78a1dbbf31d7610fc1f9c1/.github/workflows/test.yml#L29-L31,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816877910,Don't test Python 3.7 against textual, https://github.com/simonw/sqlite-utils/issues/572#issuecomment-1646660777,https://api.github.com/repos/simonw/sqlite-utils/issues/572,1646660777,IC_kwDOCGYnMM5iJgyp,9599,simonw,2023-07-22T19:59:13Z,2023-07-22T19:59:13Z,OWNER,I don't know where that is coming from! I can't see `textual` as a dependency we are pulling in anywhere.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816877910,Don't test Python 3.7 against textual, https://github.com/simonw/sqlite-utils/issues/565#issuecomment-1646659809,https://api.github.com/repos/simonw/sqlite-utils/issues/565,1646659809,IC_kwDOCGYnMM5iJgjh,9599,simonw,2023-07-22T19:53:56Z,2023-07-22T19:53:56Z,OWNER,"CLI documentation: - https://sqlite-utils.datasette.io/en/latest/cli.html#renaming-a-table - https://sqlite-utils.datasette.io/en/latest/cli-reference.html#rename-table","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1786258502,Table renaming: db.rename_table() and sqlite-utils rename-table, https://github.com/simonw/sqlite-utils/issues/565#issuecomment-1646658978,https://api.github.com/repos/simonw/sqlite-utils/issues/565,1646658978,IC_kwDOCGYnMM5iJgWi,9599,simonw,2023-07-22T19:48:54Z,2023-07-22T19:48:54Z,OWNER,"Python method documentation: - https://sqlite-utils.datasette.io/en/latest/reference.html#sqlite_utils.db.Database.rename_table - https://sqlite-utils.datasette.io/en/latest/python-api.html#renaming-a-table","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1786258502,Table renaming: db.rename_table() and sqlite-utils rename-table, https://github.com/simonw/sqlite-utils/issues/565#issuecomment-1646657849,https://api.github.com/repos/simonw/sqlite-utils/issues/565,1646657849,IC_kwDOCGYnMM5iJgE5,9599,simonw,2023-07-22T19:42:02Z,2023-07-22T19:42:02Z,OWNER,"Manually testing new `rename-table` command: ``` $ sqlite-utils schema /tmp/f.db CREATE TABLE [foo] ( [id] INTEGER, [name] TEXT ); $ sqlite-utils rename-table /tmp/f.db bad-table hi Error: Table ""bad-table"" could not be renamed. no such table: bad-table $ sqlite-utils rename-table /tmp/f.db foo foo Error: Table ""foo"" could not be renamed. there is already another table or index with this name: foo $ sqlite-utils rename-table /tmp/f.db foo bar $ sqlite-utils schema /tmp/f.db CREATE TABLE ""bar"" ( [id] INTEGER, [name] TEXT ); ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1786258502,Table renaming: db.rename_table() and sqlite-utils rename-table, https://github.com/simonw/sqlite-utils/issues/565#issuecomment-1646657324,https://api.github.com/repos/simonw/sqlite-utils/issues/565,1646657324,IC_kwDOCGYnMM5iJf8s,9599,simonw,2023-07-22T19:39:06Z,2023-07-22T19:39:06Z,OWNER,"> Also need a design for an option for the `.transform()` method to indicate that the new table should be created with a new name without dropping the old one. I think `keep_table=""name_of_table""` is good for this.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1786258502,Table renaming: db.rename_table() and sqlite-utils rename-table, https://github.com/simonw/sqlite-utils/issues/565#issuecomment-1646656246,https://api.github.com/repos/simonw/sqlite-utils/issues/565,1646656246,IC_kwDOCGYnMM5iJfr2,9599,simonw,2023-07-22T19:32:07Z,2023-07-22T19:32:07Z,OWNER,"Trying out a simple first implementation: ```pycon >>> from sqlite_utils import Database >>> db = Database(memory=True, tracer=print) PRAGMA recursive_triggers=on; None >>> db[""foo""].insert({""id"": 1}) select name from sqlite_master where type = 'view' None select name from sqlite_master where type = 'table' None select name from sqlite_master where type = 'view' None select name from sqlite_master where type = 'table' None select name from sqlite_master where type = 'view' None CREATE TABLE [foo] ( [id] INTEGER ); None select name from sqlite_master where type = 'view' None INSERT INTO [foo] ([id]) VALUES (?); [1] select name from sqlite_master where type = 'table' None select name from sqlite_master where type = 'table' None PRAGMA table_info([foo]) None
>>> db.rename_table(""foo"", ""baz"") ALTER TABLE [foo] RENAME TO [baz] None >>> print(db.schema) select sql from sqlite_master where sql is not null None CREATE TABLE ""baz"" ( [id] INTEGER ); ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1786258502,Table renaming: db.rename_table() and sqlite-utils rename-table, https://github.com/simonw/sqlite-utils/issues/568#issuecomment-1646655272,https://api.github.com/repos/simonw/sqlite-utils/issues/568,1646655272,IC_kwDOCGYnMM5iJfco,9599,simonw,2023-07-22T19:25:35Z,2023-07-22T19:25:35Z,OWNER,"Here's why that test broke: https://github.com/simonw/sqlite-utils/blob/58b577279fcd5ef6ce88f88b28668dffebfe7f44/sqlite_utils/db.py#L960-L964 I added an extra `if self[name].exists()` check to the `db.create_table()` method.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816851056,"table.create(..., replace=True)", https://github.com/simonw/sqlite-utils/issues/568#issuecomment-1646654818,https://api.github.com/repos/simonw/sqlite-utils/issues/568,1646654818,IC_kwDOCGYnMM5iJfVi,9599,simonw,2023-07-22T19:22:40Z,2023-07-22T19:22:40Z,OWNER,"I think this broke a test: ``` $ pytest tests/test_tracer.py =============================================== test session starts ================================================ platform darwin -- Python 3.11.4, pytest-7.2.2, pluggy-1.0.0 rootdir: /Users/simon/Dropbox/Development/sqlite-utils plugins: icdiff-0.6, hypothesis-6.68.2 collected 2 items tests/test_tracer.py F. [100%] ===================================================== FAILURES ===================================================== ___________________________________________________ test_tracer ____________________________________________________ def test_tracer(): collected = [] db = Database( memory=True, tracer=lambda sql, params: collected.append((sql, params)) ) db[""dogs""].insert({""name"": ""Cleopaws""}) db[""dogs""].enable_fts([""name""]) db[""dogs""].search(""Cleopaws"") > assert collected == [ (""PRAGMA recursive_triggers=on;"", None), (""select name from sqlite_master where type = 'view'"", None), (""select name from sqlite_master where type = 'table'"", None), (""select name from sqlite_master where type = 'view'"", None), (""CREATE TABLE [dogs] (\n [name] TEXT\n);\n "", None), (""select name from sqlite_master where type = 'view'"", None), (""INSERT INTO [dogs] ([name]) VALUES (?);"", [""Cleopaws""]), (""select name from sqlite_master where type = 'view'"", None), ( ""CREATE VIRTUAL TABLE [dogs_fts] USING FTS5 (\n [name],\n content=[dogs]\n)"", None, ), ( ""INSERT INTO [dogs_fts] (rowid, [name])\n SELECT rowid, [name] FROM [dogs];"", None, ), (""select name from sqlite_master where type = 'view'"", None), ] E assert equals failed E [ [ E ('PRAGMA recursive_triggers=on;', None), ('PRAGMA recursive_triggers=on;', None), E ( E ""select name from sqlite_master where type = E 'view'"", E None, ... E E ...Full output truncated (13 lines hidden), use '-vv' to show tests/test_tracer.py:12: AssertionError ============================================= short test summary info ============================================== FAILED tests/test_tracer.py::test_tracer - assert equals failed =========================================== 1 failed, 1 passed in 0.05s ============================================ ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816851056,"table.create(..., replace=True)", https://github.com/simonw/sqlite-utils/issues/567#issuecomment-1646654383,https://api.github.com/repos/simonw/sqlite-utils/issues/567,1646654383,IC_kwDOCGYnMM5iJfOv,9599,simonw,2023-07-22T19:20:16Z,2023-07-22T19:20:16Z,OWNER,"Here's documentation for the new plugins mechanism, including a very short tutorial on writing a new plugin (inspired by https://llm.datasette.io/en/stable/plugins/tutorial-model-plugin.html): https://sqlite-utils.datasette.io/en/latest/plugins.html","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1801394744,Plugin system, https://github.com/simonw/sqlite-utils/issues/569#issuecomment-1646654275,https://api.github.com/repos/simonw/sqlite-utils/issues/569,1646654275,IC_kwDOCGYnMM5iJfND,9599,simonw,2023-07-22T19:19:35Z,2023-07-22T19:19:35Z,OWNER,Documentation: https://sqlite-utils.datasette.io/en/latest/plugins.html#register-commands-cli,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816852402,register_command plugin hook, https://github.com/simonw/sqlite-utils/issues/568#issuecomment-1646653610,https://api.github.com/repos/simonw/sqlite-utils/issues/568,1646653610,IC_kwDOCGYnMM5iJfCq,9599,simonw,2023-07-22T19:14:56Z,2023-07-22T19:14:56Z,OWNER,"Manual testing of CLI command as well: ``` $ sqlite-utils create-table /tmp/f.db foo id integer $ sqlite-utils create-table /tmp/f.db foo id integer Error: Table ""foo"" already exists. Use --replace to delete and replace it. $ sqlite-utils create-table /tmp/f.db foo id integer --replace $ sqlite-utils create-table /tmp/f.db foo id $ sqlite-utils schema /tmp/f.db CREATE TABLE [foo] ( [id] INTEGER ); $ sqlite-utils create-table /tmp/f.db foo id integer name str --transform Error: column types must be one of ('INTEGER', 'TEXT', 'FLOAT', 'BLOB') $ sqlite-utils create-table /tmp/f.db foo id integer name text --transform $ sqlite-utils schema /tmp/f.db CREATE TABLE ""foo"" ( [id] INTEGER, [name] TEXT ); $ sqlite-utils create-table /tmp/f.db foo id integer name text --ignore $ sqlite-utils create-table /tmp/f.db foo id integer name text --replace $ sqlite-utils schema /tmp/f.db CREATE TABLE [foo] ( [id] INTEGER, [name] TEXT ); ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816851056,"table.create(..., replace=True)", https://github.com/simonw/sqlite-utils/issues/568#issuecomment-1646653382,https://api.github.com/repos/simonw/sqlite-utils/issues/568,1646653382,IC_kwDOCGYnMM5iJe_G,9599,simonw,2023-07-22T19:13:20Z,2023-07-22T19:13:20Z,OWNER,"Demo: ```pycon >>> from sqlite_utils import Database >>> db = Database(memory=True) >>> db[""foo""].create({""id"": int})
>>> db[""foo""].create({""id"": int}) Traceback (most recent call last): File """", line 1, in File ""/Users/simon/Dropbox/Development/sqlite-utils/sqlite_utils/db.py"", line 1647, in create self.db.create_table( File ""/Users/simon/Dropbox/Development/sqlite-utils/sqlite_utils/db.py"", line 1030, in create_table self.execute(sql) File ""/Users/simon/Dropbox/Development/sqlite-utils/sqlite_utils/db.py"", line 510, in execute return self.conn.execute(sql) ^^^^^^^^^^^^^^^^^^^^^^ sqlean.dbapi2.OperationalError: table [foo] already exists >>> db[""foo""].create({""id"": int}, ignore=True)
>>> db[""foo""].create({""id"": int, ""name"": str}, replace=True)
>>> db[""foo""].create({""id"": int, ""name"": str, ""age"": int}, transform=True)
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816851056,"table.create(..., replace=True)", https://github.com/simonw/sqlite-utils/issues/568#issuecomment-1646652105,https://api.github.com/repos/simonw/sqlite-utils/issues/568,1646652105,IC_kwDOCGYnMM5iJerJ,9599,simonw,2023-07-22T19:05:13Z,2023-07-22T19:05:13Z,OWNER,I think this is `replace=True` and `ignore=True` to match the CLI. And refactoring the CLI to use them.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816851056,"table.create(..., replace=True)", https://github.com/simonw/datasette/issues/2106#issuecomment-1646648262,https://api.github.com/repos/simonw/datasette/issues/2106,1646648262,IC_kwDOBm6k_c5iJdvG,9599,simonw,2023-07-22T18:42:20Z,2023-07-22T18:42:20Z,OWNER,"Tested this locally with: ```bash datasette install -e ../datasette-graphql ``` Running `datasette plugins` confirmed that the plugin had been installed.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816857442,`datasette install -e` option, https://github.com/simonw/datasette/issues/2106#issuecomment-1646646931,https://api.github.com/repos/simonw/datasette/issues/2106,1646646931,IC_kwDOBm6k_c5iJdaT,9599,simonw,2023-07-22T18:34:04Z,2023-07-22T18:34:04Z,OWNER,Here's the diff for adding it to `sqlite-utils`: https://github.com/simonw/sqlite-utils/commit/ef31210bf06f920e0890e171c3198f0b0dc8d72d,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816857442,`datasette install -e` option, https://github.com/simonw/sqlite-utils/issues/569#issuecomment-1646645990,https://api.github.com/repos/simonw/sqlite-utils/issues/569,1646645990,IC_kwDOCGYnMM5iJdLm,9599,simonw,2023-07-22T18:29:40Z,2023-07-22T18:30:16Z,OWNER,"Example plugin: https://gist.github.com/simonw/ccfbbf9b384a38ac7535b01849f57daf ```bash sqlite-utils install https://gist.github.com/simonw/ccfbbf9b384a38ac7535b01849f57daf/archive/cd7960e476c441a3c5f619e2a44a641a39b91467.zip ``` `pyproject.toml`: ```toml [project] name = ""sqlite-utils-hello-world"" version = ""0.1"" [project.entry-points.sqlite_utils] hello_world = ""sqlite_utils_hello_world"" ``` `sqlite_utils_hello_world.py`: ```python import click import sqlite_utils @sqlite_utils.hookimpl def register_commands(cli): @cli.command() def hello_world(): ""Say hello world"" click.echo(""Hello world!"") ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816852402,register_command plugin hook, https://github.com/simonw/sqlite-utils/issues/569#issuecomment-1646643676,https://api.github.com/repos/simonw/sqlite-utils/issues/569,1646643676,IC_kwDOCGYnMM5iJcnc,9599,simonw,2023-07-22T18:18:24Z,2023-07-22T18:18:24Z,OWNER,"Here's where I added that to LLM: https://github.com/simonw/llm/commit/a396950f7934e82a9968703bb3ce9ab7ab62f7f8 - https://github.com/simonw/llm/issues/49","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816852402,register_command plugin hook, https://github.com/simonw/sqlite-utils/issues/567#issuecomment-1646643450,https://api.github.com/repos/simonw/sqlite-utils/issues/567,1646643450,IC_kwDOCGYnMM5iJcj6,9599,simonw,2023-07-22T18:17:18Z,2023-07-22T18:17:18Z,OWNER,I'm going to start by adding the `register_command` hook using the exact same pattern as Datasette and LLM.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1801394744,Plugin system, https://github.com/simonw/sqlite-utils/issues/567#issuecomment-1646643379,https://api.github.com/repos/simonw/sqlite-utils/issues/567,1646643379,IC_kwDOCGYnMM5iJciz,9599,simonw,2023-07-22T18:16:54Z,2023-07-22T18:16:54Z,OWNER,"> Would this possibly make a bunch of `x-to-sqlite` tools obsolete? Or nudge some to become plugins? Yeah, it could do! That's not a terrible idea to be honest, those things have really been proliferating. Alternatively, they could each register themselves as plugins in addition - so if you install e.g. `pocket-to-sqlite` you could then optionally also run it as `sqlite-utils pocket-to-sqlite ...` The benefit there is for people who install `sqlite-utils` from Homebrew, where it gets its own virtual environment. They could run: ```bash brew install sqlite-utils sqlite-utils install pocket-to-sqlite sqlite-utils pocket-to-sqlite ... ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1801394744,Plugin system, https://github.com/simonw/sqlite-utils/issues/568#issuecomment-1646642959,https://api.github.com/repos/simonw/sqlite-utils/issues/568,1646642959,IC_kwDOCGYnMM5iJccP,9599,simonw,2023-07-22T18:14:49Z,2023-07-22T18:14:49Z,OWNER,Here's where those are implemented for the `create-table` CLI command: https://github.com/simonw/sqlite-utils/blob/f7af23837deab5c98dae9441d1f68318065d7d8c/sqlite_utils/cli.py#L1543-L1564,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816851056,"table.create(..., replace=True)", https://github.com/simonw/sqlite-utils/issues/568#issuecomment-1646642666,https://api.github.com/repos/simonw/sqlite-utils/issues/568,1646642666,IC_kwDOCGYnMM5iJcXq,9599,simonw,2023-07-22T18:13:19Z,2023-07-22T18:13:19Z,OWNER,"https://sqlite-utils.datasette.io/en/stable/cli-reference.html#create-table ```bash sqlite-utils create-table ... --replace ``` That also has `--ignore`: ``` --ignore If table already exists, do nothing --replace If table already exists, replace it --transform If table already exists, try to transform the schema ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1816851056,"table.create(..., replace=True)",