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