issue_comments
8,883 rows where user = 9599 sorted by updated_at descending
This data as json, CSV (advanced)
created_at (date) >30 ✖
- 2021-03-22 63
- 2021-11-19 59
- 2020-10-15 52
- 2020-09-22 51
- 2020-10-30 47
- 2022-03-21 45
- 2020-06-09 42
- 2020-12-18 42
- 2022-10-26 42
- 2020-06-18 41
- 2022-06-14 39
- 2022-10-25 39
- 2020-05-27 38
- 2020-12-30 38
- 2021-12-16 38
- 2022-01-09 38
- 2020-10-20 37
- 2022-10-27 37
- 2021-11-16 36
- 2020-09-15 34
- 2021-11-20 34
- 2022-01-20 34
- 2022-03-19 34
- 2020-06-08 33
- 2020-06-01 32
- 2020-10-09 32
- 2021-05-27 31
- 2020-09-21 30
- 2021-08-13 30
- 2021-11-29 30
- …
user 1
- simonw · 7,584 ✖
id | html_url | issue_url | node_id | user | created_at | updated_at ▲ | author_association | body | reactions | issue | performed_via_github_app |
---|---|---|---|---|---|---|---|---|---|---|---|
1301646670 | https://github.com/simonw/datasette/issues/1855#issuecomment-1301646670 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5NlY1O | simonw 9599 | 2022-11-03T05:11:26Z | 2022-11-03T05:11:26Z | OWNER | That still needs comprehensive tests before I land it. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1301646493 | https://github.com/simonw/datasette/issues/1855#issuecomment-1301646493 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5NlYyd | simonw 9599 | 2022-11-03T05:11:06Z | 2022-11-03T05:11:06Z | OWNER | Built a prototype of the above: ```diff diff --git a/datasette/default_permissions.py b/datasette/default_permissions.py index 32b0c758..f68aa38f 100644 --- a/datasette/default_permissions.py +++ b/datasette/default_permissions.py @@ -6,8 +6,8 @@ import json import time -@hookimpl(tryfirst=True) -def permission_allowed(datasette, actor, action, resource): +@hookimpl(tryfirst=True, specname="permission_allowed") +def permission_allowed_default(datasette, actor, action, resource): async def inner(): if action in ( "permissions-debug", @@ -57,6 +57,44 @@ def permission_allowed(datasette, actor, action, resource): return inner +@hookimpl(specname="permission_allowed") +def permission_allowed_actor_restrictions(actor, action, resource): + if actor is None: + return None + r = actor.get("_r") + if not _r: + # No restrictions, so we have no opinion + return None + action_initials = "".join([word[0] for word in action.split("-")]) + # If _r is defined then we use those to further restrict the actor + # Crucially, we only use this to say NO (return False) - we never + # use it to return YES (True) because that might over-ride other + # restrictions placed on this actor + all_allowed = _r.get("a") + if all_allowed is not None: + assert isinstance(all_allowed, list) + if action_initials in all_allowed: + return None + # How about for the current database? + if action in ("view-database", "view-database-download", "execute-sql"): + database_allowed = _r.get("d", {}).get(resource) + if database_allowed is not None: + assert isinstance(database_allowed, list) + if action_initials in database_allowed: + return None + # Or the current table? That's any time the resource is (database, table) + if not isinstance(resource, str) and len(resource) == 2: + database, table = resource + table_allowed = _r.get("t", {}).get(database, {}).get(table) + # TODO: What should this do for canned queries? + if table_allowed is not None: + assert isinstance(table_allowed, list) + if action_initials in table_allowed: + return None + # This action is not specifically allowed, so reject it + return False + + @hookimpl def actor_from_request(datasette, request): prefix = "dstok" ``` |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1301639741 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301639741 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlXI9 | simonw 9599 | 2022-11-03T04:58:21Z | 2022-11-03T04:58:21Z | OWNER | The whole |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Tool for simulating permission checks against actors 1434094365 | |
1301639370 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301639370 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlXDK | simonw 9599 | 2022-11-03T04:57:21Z | 2022-11-03T04:57:21Z | OWNER | The plugin hook would be called |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Tool for simulating permission checks against actors 1434094365 | |
1301638918 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301638918 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlW8G | simonw 9599 | 2022-11-03T04:56:06Z | 2022-11-03T04:56:06Z | OWNER | I've also introduced a new concept of a permission abbreviation, which like the permission name needs to be globally unique. That's a problem for plugins - they might just be able to guarantee that their permission long-form name is unique among other plugins (through sensible naming conventions) but the thing where they declare a initial-letters-only abbreviation is far more risky. I think abbreviations are optional - they are provided for core permissions but plugins are advised not to use them. Also Datasette could check that the installed plugins do not provide conflicting permissions on startup and refuse to start if they do. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Tool for simulating permission checks against actors 1434094365 | |
1301638156 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301638156 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlWwM | simonw 9599 | 2022-11-03T04:54:00Z | 2022-11-03T04:54:00Z | OWNER | If I have the permissions defined like this:
On the other hand though, plugins that introduce their own permissions - like https://datasette.io/plugins/datasette-edit-schema - will need a way to register those permissions with Datasette core. Probably another plugin hook. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Tool for simulating permission checks against actors 1434094365 | |
1301635906 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301635906 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlWNC | simonw 9599 | 2022-11-03T04:48:09Z | 2022-11-03T04:48:09Z | OWNER | I built this prototype on the http://127.0.0.1:8001/-/allow-debug page, which is open to anyone to visit. But... I just realized that using this tool can leak information - you can use it to guess the names of invisible databases and tables and run theoretical permission checks against them. Using the tool also pollutes the list of permission checks that show up on the root-anlo So.... I'm going to restrict the usage of this tool to users with access to |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Tool for simulating permission checks against actors 1434094365 | |
1301635340 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301635340 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlWEM | simonw 9599 | 2022-11-03T04:46:41Z | 2022-11-03T04:46:41Z | OWNER | Built this prototype: In building it I realized I needed to know which permissions took a table, a database, both or neither. So I had to bake that into the code. Here's the prototype so far (which includes a prototype of the logic for the ```diff diff --git a/datasette/default_permissions.py b/datasette/default_permissions.py index 32b0c758..f68aa38f 100644 --- a/datasette/default_permissions.py +++ b/datasette/default_permissions.py @@ -6,8 +6,8 @@ import json import time -@hookimpl(tryfirst=True) -def permission_allowed(datasette, actor, action, resource): +@hookimpl(tryfirst=True, specname="permission_allowed") +def permission_allowed_default(datasette, actor, action, resource): async def inner(): if action in ( "permissions-debug", @@ -57,6 +57,44 @@ def permission_allowed(datasette, actor, action, resource): return inner +@hookimpl(specname="permission_allowed") +def permission_allowed_actor_restrictions(actor, action, resource): + if actor is None: + return None + r = actor.get("_r") + if not _r: + # No restrictions, so we have no opinion + return None + action_initials = "".join([word[0] for word in action.split("-")]) + # If _r is defined then we use those to further restrict the actor + # Crucially, we only use this to say NO (return False) - we never + # use it to return YES (True) because that might over-ride other + # restrictions placed on this actor + all_allowed = _r.get("a") + if all_allowed is not None: + assert isinstance(all_allowed, list) + if action_initials in all_allowed: + return None + # How about for the current database? + if action in ("view-database", "view-database-download", "execute-sql"): + database_allowed = _r.get("d", {}).get(resource) + if database_allowed is not None: + assert isinstance(database_allowed, list) + if action_initials in database_allowed: + return None + # Or the current table? That's any time the resource is (database, table) + if not isinstance(resource, str) and len(resource) == 2: + database, table = resource + table_allowed = _r.get("t", {}).get(database, {}).get(table) + # TODO: What should this do for canned queries? + if table_allowed is not None: + assert isinstance(table_allowed, list) + if action_initials in table_allowed: + return None + # This action is not specifically allowed, so reject it + return False + + @hookimpl def actor_from_request(datasette, request): prefix = "dstok" diff --git a/datasette/templates/allow_debug.html b/datasette/templates/allow_debug.html index 0f1b30f0..ae43f0f5 100644 --- a/datasette/templates/allow_debug.html +++ b/datasette/templates/allow_debug.html @@ -35,7 +35,7 @@ p.message-warning { Use this tool to try out different actor and allow combinations. See Defining permissions with "allow" blocks for documentation. -<form action="{{ urls.path('-/allow-debug') }}" method="get"> +<form action="{{ urls.path('-/allow-debug') }}" method="get" style="margin-bottom: 1em"> <label>Allow block</label> <textarea name="allow">{{ allow_input }}</textarea> @@ -55,4 +55,82 @@ p.message-warning {{% if result == "False" %} Result: deny {% endif %}+ Test permission check+ +This tool lets you simulate an actor and a permission check for that actor. + +<form action="{{ urls.path('-/allow-debug') }}" id="debug-post" method="post" style="margin-bottom: 1em"> + +
+
+ <label>Actor</label> + <textarea name="actor">{% if actor_input %}{{ actor_input }}{% else %}{"id": "root"}{% endif %}</textarea> +
+
+ <label>Permission check</label> +<label for="permission" style="display:block">Permission</label> + <select name="permission" id="permission"> + {% for permission in [ + "view-instance", + "view-database", + "view-database-download", + "view-table", + "view-query", + "insert-row", + "delete-row", + "drop-table", + "execute-sql", + "permissions-debug", + "debug-menu"] %} + <option value="{{ permission }}">{{ permission }}</option> + {% endfor %} + </select> + <label for="resource_1">Database name</label> +<label for="resource_2">Table or query name</label> +
+
+
+</form>
+
+<script>
+var rawPerms = {{ permissions|tojson }};
+var permissions = Object.fromEntries(rawPerms.map(([label, abbr, needs_resource_1, needs_resource_2, def]) => [label, {needs_resource_1, needs_resource_2, def}]))
+var permissionSelect = document.getElementById('permission');
+var resource1 = document.getElementById('resource_1');
+var resource2 = document.getElementById('resource_2');
+function updateResourceVisibility() {
+ var permission = permissionSelect.value;
+ var {needs_resource_1, needs_resource_2} = permissions[permission];
+ if (needs_resource_1) {
+ resource1.closest('p').style.display = 'block';
+ } else {
+ resource1.closest('p').style.display = 'none';
+ }
+ if (needs_resource_2) {
+ resource2.closest('p').style.display = 'block';
+ } else {
+ resource2.closest('p').style.display = 'none';
+ }
+}
+permissionSelect.addEventListener('change', updateResourceVisibility);
+updateResourceVisibility();
+
+// When #debug-post form is submitted, use fetch() to POST data
+var debugPost = document.getElementById('debug-post');
+debugPost.addEventListener('submit', function(ev) {
+ ev.preventDefault();
+ var formData = new FormData(debugPost);
+ console.log(formData);
+ fetch(debugPost.action, {
+ method: 'POST',
+ body: new URLSearchParams(formData),
+ }).then(function(response) {
+ return response.json();
+ }).then(function(data) {
+ alert(JSON.stringify(data, null, 4));
+ });
+});
+</script>
+ + {% endblock %} diff --git a/datasette/views/special.py b/datasette/views/special.py index 9922a621..d46fc280 100644 --- a/datasette/views/special.py +++ b/datasette/views/special.py @@ -1,6 +1,8 @@ import json +from datasette.permissions import PERMISSIONS from datasette.utils.asgi import Response, Forbidden from datasette.utils import actor_matches_allow, add_cors_headers +from datasette.permissions import PERMISSIONS from .base import BaseView import secrets import time @@ -138,9 +140,34 @@ class AllowDebugView(BaseView): "error": "\n\n".join(errors) if errors else "", "actor_input": actor_input, "allow_input": allow_input, + "permissions": PERMISSIONS, }, )
class MessagesDebugView(BaseView): name = "messages_debug" ``` |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Tool for simulating permission checks against actors 1434094365 | |
1301594495 | https://github.com/simonw/datasette/issues/1855#issuecomment-1301594495 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5NlMF_ | simonw 9599 | 2022-11-03T03:11:17Z | 2022-11-03T03:11:17Z | OWNER | Maybe the way to do this is through a new standard mechanism on the actor: a set of additional restrictions, e.g.:
The way this works is there's a default permission_allowed(datasette, actor, action, resource) hook which only consults these, and crucially just says NO if those rules do not match. In this way it would apply as an extra layer of permission rules over the defaults (which for this |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1299607082 | https://github.com/simonw/datasette/issues/1871#issuecomment-1299607082 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5Ndm4q | simonw 9599 | 2022-11-02T05:45:31Z | 2022-11-02T05:45:31Z | OWNER | I'm going to add a link to the Datasette API docs for the current running version of Datasette, e.g. to https://docs.datasette.io/en/0.63/json_api.html |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1299600257 | https://github.com/simonw/datasette/issues/1871#issuecomment-1299600257 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NdlOB | simonw 9599 | 2022-11-02T05:36:40Z | 2022-11-02T05:36:40Z | OWNER | The API Explorer should definitely link to the And it should probably go in the Datasette application menu? |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1299599461 | https://github.com/simonw/datasette/issues/1871#issuecomment-1299599461 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NdlBl | simonw 9599 | 2022-11-02T05:35:36Z | 2022-11-02T05:36:15Z | OWNER | Here's a slightly wild idea: what if there was a button on Only reason I don't want to show these to everyone is that I don't think this is a very user-friendly feature: if you don't know what an API is I don't want to expose you to it unnecessarily. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1299598570 | https://github.com/simonw/datasette/issues/1871#issuecomment-1299598570 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5Ndkzq | simonw 9599 | 2022-11-02T05:34:28Z | 2022-11-02T05:34:28Z | OWNER | This is pretty useful now. Two features I still want to add:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1299597066 | https://github.com/simonw/datasette/issues/1871#issuecomment-1299597066 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NdkcK | simonw 9599 | 2022-11-02T05:32:22Z | 2022-11-02T05:32:22Z | OWNER | Demo of the latest API explorer: |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1299388341 | https://github.com/simonw/datasette/issues/1871#issuecomment-1299388341 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5Ncxe1 | simonw 9599 | 2022-11-02T00:24:28Z | 2022-11-02T00:25:00Z | OWNER | I want JSON syntax highlighting. https://github.com/luyilin/json-format-highlight is an MIT licensed tiny highlighter that looks decent for this. https://unpkg.com/json-format-highlight@1.0.1/dist/json-format-highlight.js |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1299349741 | https://github.com/simonw/datasette/issues/1871#issuecomment-1299349741 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NcoDt | simonw 9599 | 2022-11-01T23:22:55Z | 2022-11-01T23:22:55Z | OWNER | It's weird that the API explorer only lets you explore POST APIs. It should probably also let you explore GET APIs, or be renamed. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1299098458 | https://github.com/simonw/datasette/issues/1879#issuecomment-1299098458 | https://api.github.com/repos/simonw/datasette/issues/1879 | IC_kwDOBm6k_c5Nbqta | simonw 9599 | 2022-11-01T20:27:40Z | 2022-11-01T20:33:52Z | OWNER | https://github.com/simonw/datasette-x-forwarded-host/blob/main/datasette_x_forwarded_host/init.py could happen in core controlled by:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make it easier to fix URL proxy problems 1432037325 | |
1299102108 | https://github.com/simonw/datasette/issues/1879#issuecomment-1299102108 | https://api.github.com/repos/simonw/datasette/issues/1879 | IC_kwDOBm6k_c5Nbrmc | simonw 9599 | 2022-11-01T20:30:54Z | 2022-11-01T20:33:06Z | OWNER | One idea: add a |
{ "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make it easier to fix URL proxy problems 1432037325 | |
1299102755 | https://github.com/simonw/datasette/issues/1879#issuecomment-1299102755 | https://api.github.com/repos/simonw/datasette/issues/1879 | IC_kwDOBm6k_c5Nbrwj | simonw 9599 | 2022-11-01T20:31:37Z | 2022-11-01T20:31:37Z | OWNER | And some JavaScript that can spot if Datasette thinks it is being served over HTTP when it's actually being served over HTTPS. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make it easier to fix URL proxy problems 1432037325 | |
1299096850 | https://github.com/simonw/datasette/issues/1879#issuecomment-1299096850 | https://api.github.com/repos/simonw/datasette/issues/1879 | IC_kwDOBm6k_c5NbqUS | simonw 9599 | 2022-11-01T20:26:12Z | 2022-11-01T20:26:12Z | OWNER | The other relevant plugin here is https://datasette.io/plugins/datasette-x-forwarded-host Maybe that should be rolled into core too? |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make it easier to fix URL proxy problems 1432037325 | |
1299090678 | https://github.com/simonw/datasette/issues/1879#issuecomment-1299090678 | https://api.github.com/repos/simonw/datasette/issues/1879 | IC_kwDOBm6k_c5Nboz2 | simonw 9599 | 2022-11-01T20:20:28Z | 2022-11-01T20:20:28Z | OWNER | My first step in debugging these is to install https://datasette.io/plugins/datasette-debug-asgi - but now I'm thinking maybe something like that should be part of core. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make it easier to fix URL proxy problems 1432037325 | |
1299073433 | https://github.com/simonw/datasette/issues/1862#issuecomment-1299073433 | https://api.github.com/repos/simonw/datasette/issues/1862 | IC_kwDOBm6k_c5NbkmZ | simonw 9599 | 2022-11-01T20:04:31Z | 2022-11-01T20:04:31Z | OWNER | It really feels like this should be accompanied by a https://sqlite-utils.datasette.io/en/stable/cli.html#cli-create-table |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Create a new table from one or more records, `sqlite-utils` style 1425011030 | |
1299071456 | https://github.com/simonw/datasette/issues/1878#issuecomment-1299071456 | https://api.github.com/repos/simonw/datasette/issues/1878 | IC_kwDOBm6k_c5NbkHg | simonw 9599 | 2022-11-01T20:02:43Z | 2022-11-01T20:02:43Z | OWNER | Note that "update" is partially covered by the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
/db/table/-/upsert API 1432013704 | |
1298919552 | https://github.com/simonw/datasette/issues/1873#issuecomment-1298919552 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5Na_CA | simonw 9599 | 2022-11-01T18:11:27Z | 2022-11-01T18:11:27Z | OWNER | I forgot to document
I think my validation logic here will get caught out by the fact that |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1298905135 | https://github.com/simonw/datasette/issues/1873#issuecomment-1298905135 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5Na7gv | simonw 9599 | 2022-11-01T17:59:59Z | 2022-11-01T17:59:59Z | OWNER | It's a bit surprising that you can send Three options:
I'm picking 3 - I'm going to change it to be called |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1298885451 | https://github.com/simonw/datasette/issues/1873#issuecomment-1298885451 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5Na2tL | simonw 9599 | 2022-11-01T17:42:20Z | 2022-11-01T17:42:20Z | OWNER | Design decision:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1298879701 | https://github.com/simonw/sqlite-utils/issues/506#issuecomment-1298879701 | https://api.github.com/repos/simonw/sqlite-utils/issues/506 | IC_kwDOCGYnMM5Na1TV | simonw 9599 | 2022-11-01T17:37:13Z | 2022-11-01T17:37:13Z | OWNER | The question I was originally trying to answer here was this: how many rows were actually inserted by that call to I don't know that So I think if people need |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make `cursor.rowcount` accessible (wontfix) 1429029604 | |
1298877872 | https://github.com/simonw/sqlite-utils/issues/506#issuecomment-1298877872 | https://api.github.com/repos/simonw/sqlite-utils/issues/506 | IC_kwDOCGYnMM5Na02w | simonw 9599 | 2022-11-01T17:35:30Z | 2022-11-01T17:35:30Z | OWNER | This may not make sense. First, So I tried this prototype:
+After executing a query the db.execute(sql, params) diff --git a/sqlite_utils/db.py b/sqlite_utils/db.py index a06f4b7..c19c2dd 100644 --- a/sqlite_utils/db.py +++ b/sqlite_utils/db.py @@ -294,6 +294,8 @@ class Database:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make `cursor.rowcount` accessible (wontfix) 1429029604 | |
1298856054 | https://github.com/simonw/datasette/issues/1876#issuecomment-1298856054 | https://api.github.com/repos/simonw/datasette/issues/1876 | IC_kwDOBm6k_c5Navh2 | simonw 9599 | 2022-11-01T17:16:01Z | 2022-11-01T17:16:01Z | OWNER |
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
SQL query should wrap on SQL interrupted screen 1431786951 | |
1298854321 | https://github.com/simonw/datasette/issues/1876#issuecomment-1298854321 | https://api.github.com/repos/simonw/datasette/issues/1876 | IC_kwDOBm6k_c5NavGx | simonw 9599 | 2022-11-01T17:14:33Z | 2022-11-01T17:14:33Z | OWNER | I could use a |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
SQL query should wrap on SQL interrupted screen 1431786951 | |
1296403316 | https://github.com/simonw/datasette/issues/1864#issuecomment-1296403316 | https://api.github.com/repos/simonw/datasette/issues/1864 | IC_kwDOBm6k_c5NRYt0 | simonw 9599 | 2022-10-31T00:39:43Z | 2022-10-31T00:39:43Z | OWNER | It looks like SQLite has features for this already: https://www.sqlite.org/foreignkeys.html#fk_actions
On that basis, I'm not going to implement anything additional in the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Delete a single record from an existing table 1425029275 | |
1296402071 | https://github.com/simonw/datasette/issues/1864#issuecomment-1296402071 | https://api.github.com/repos/simonw/datasette/issues/1864 | IC_kwDOBm6k_c5NRYaX | simonw 9599 | 2022-10-31T00:37:09Z | 2022-10-31T00:37:09Z | OWNER | I need to think about what happens if you delete a row that is the target of a foreign key from another row. https://www.sqlite.org/foreignkeys.html#fk_enable shows that SQLite will only actively enforce these relationships (e.g. throw an error if you try to delete a row that is referenced by another row) if you first run
I don't actually believe that the SQLite maintainers will ever make that the default though. Datasette doesn't turn these on at the moment, but it could be turned on by a |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Delete a single record from an existing table 1425029275 | |
1296375536 | https://github.com/simonw/datasette/issues/1864#issuecomment-1296375536 | https://api.github.com/repos/simonw/datasette/issues/1864 | IC_kwDOBm6k_c5NRR7w | simonw 9599 | 2022-10-30T23:17:11Z | 2022-10-30T23:17:11Z | OWNER | I'm a bit nervous about calling |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Delete a single record from an existing table 1425029275 | |
1296375310 | https://github.com/simonw/datasette/issues/1864#issuecomment-1296375310 | https://api.github.com/repos/simonw/datasette/issues/1864 | IC_kwDOBm6k_c5NRR4O | simonw 9599 | 2022-10-30T23:16:19Z | 2022-10-30T23:16:19Z | OWNER | Still needs tests that cover compound primary keys and rowid tables. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Delete a single record from an existing table 1425029275 | |
1296363981 | https://github.com/simonw/datasette/issues/1874#issuecomment-1296363981 | https://api.github.com/repos/simonw/datasette/issues/1874 | IC_kwDOBm6k_c5NRPHN | simonw 9599 | 2022-10-30T22:19:47Z | 2022-10-30T22:19:47Z | OWNER | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to drop a table 1429030341 | ||
1296358636 | https://github.com/simonw/sqlite-utils/issues/506#issuecomment-1296358636 | https://api.github.com/repos/simonw/sqlite-utils/issues/506 | IC_kwDOCGYnMM5NRNzs | simonw 9599 | 2022-10-30T21:52:11Z | 2022-10-30T21:52:11Z | OWNER | This could work in a similar way to |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make `cursor.rowcount` accessible (wontfix) 1429029604 | |
1296343716 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296343716 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NRKKk | simonw 9599 | 2022-10-30T20:24:55Z | 2022-10-30T20:24:55Z | OWNER | I think the key feature I need here is going to be the equivalent of |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1296343317 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296343317 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NRKEV | simonw 9599 | 2022-10-30T20:22:40Z | 2022-10-30T20:22:40Z | OWNER | So maybe they're not actually worth worrying about separately, because they are guaranteed to have a primary key set. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1296343173 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296343173 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NRKCF | simonw 9599 | 2022-10-30T20:21:54Z | 2022-10-30T20:22:20Z | OWNER | One last case to consider: https://www.sqlite.org/withoutrowid.html
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1296343014 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296343014 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NRJ_m | simonw 9599 | 2022-10-30T20:21:01Z | 2022-10-30T20:21:01Z | OWNER | Actually, for simplicity I'm going to say that you can always set the primary key, even for auto-incrementing primary key columns... but you cannot set it on pure |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1296342814 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296342814 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NRJ8e | simonw 9599 | 2022-10-30T20:20:05Z | 2022-10-30T20:20:05Z | OWNER | Some notes on what Datasette does already https://latest.datasette.io/fixtures/tags.json?_shape=array returns:
https://latest.datasette.io/fixtures/binary_data.json?_shape=array
https://latest.datasette.io/fixtures/simple_primary_key.json?_shape=array
https://latest.datasette.io/fixtures/compound_primary_key.json?_shape=array
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1296341469 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296341469 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NRJnd | simonw 9599 | 2022-10-30T20:13:50Z | 2022-10-30T20:13:50Z | OWNER | I checked and SQLite itself does allow you to set the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1296341055 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296341055 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NRJg_ | simonw 9599 | 2022-10-30T20:11:47Z | 2022-10-30T20:12:30Z | OWNER | If a table has an auto-incrementing primary key, should you be allowed to insert records with an explicit key into it? I'm torn on this one. It's something you can do with direct database access, but it's something I very rarely want to do. I'm inclined to disallow it and say that if you want that you can get it using a writable canned query instead. Likewise, I'm not going to provide a way to set the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1296339386 | https://github.com/simonw/datasette/issues/1871#issuecomment-1296339386 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NRJG6 | simonw 9599 | 2022-10-30T20:03:04Z | 2022-10-30T20:03:04Z | OWNER | I do need to skip CSRF for these API calls. I'm going to start out by doing that using the
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1296339205 | https://github.com/simonw/datasette/issues/1871#issuecomment-1296339205 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NRJEF | simonw 9599 | 2022-10-30T20:02:05Z | 2022-10-30T20:02:05Z | OWNER | Realized the API explorer doesn't need the API key piece at all - it can work with standard cookie-based auth. This also reflects how most plugins are likely to use this API, where they'll be adding JavaScript that uses |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1296131872 | https://github.com/simonw/datasette/issues/1871#issuecomment-1296131872 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NQWcg | simonw 9599 | 2022-10-30T06:27:56Z | 2022-10-30T06:27:56Z | OWNER | Initial prototype API explorer is now live at https://latest-1-0-dev.datasette.io/-/api |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1296131681 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296131681 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NQWZh | simonw 9599 | 2022-10-30T06:27:12Z | 2022-10-30T06:27:12Z | OWNER | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | ||
1296131343 | https://github.com/simonw/datasette/issues/1872#issuecomment-1296131343 | https://api.github.com/repos/simonw/datasette/issues/1872 | IC_kwDOBm6k_c5NQWUP | simonw 9599 | 2022-10-30T06:26:01Z | 2022-10-30T06:26:01Z | OWNER | Good spot fixing that! Sorry about this - it was a change in Datasette 0.63 which should have been better called out. My goal for Datasette 1.0 (which I aim to have out by the end of the year) is to introduce a formal process for avoiding problems like this, with very clear documentation when something like this might happen. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
SITE-BUSTING ERROR: "render_template() called before await ds.invoke_startup()" 1428560020 | |
1296130073 | https://github.com/simonw/datasette/issues/1871#issuecomment-1296130073 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NQWAZ | simonw 9599 | 2022-10-30T06:20:56Z | 2022-10-30T06:20:56Z | OWNER | That initial prototype looks like this: It currently shows the returned JSON from the API in an |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1296126389 | https://github.com/simonw/datasette/issues/1871#issuecomment-1296126389 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NQVG1 | simonw 9599 | 2022-10-30T06:04:48Z | 2022-10-30T06:04:48Z | OWNER | This is even more important now I have pushed: - #1866 |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1296114136 | https://github.com/simonw/datasette/issues/1871#issuecomment-1296114136 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NQSHY | simonw 9599 | 2022-10-30T05:15:40Z | 2022-10-30T05:15:40Z | OWNER | Host it at It's an input box with a path in and a textarea you can put JSON in, plus a submit button to post the request. It lists the API endpoints you can use - click on a link to populate the form field plus a example. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1295660092 | https://github.com/simonw/datasette/pull/1870#issuecomment-1295660092 | https://api.github.com/repos/simonw/datasette/issues/1870 | IC_kwDOBm6k_c5NOjQ8 | simonw 9599 | 2022-10-29T00:25:26Z | 2022-10-29T00:25:26Z | OWNER | Saw your comment here too: https://github.com/simonw/datasette/issues/1480#issuecomment-1271101072
So maybe we need a special case for containers that are intended to be run using Docker - the ones produced by Maybe a I should run some benchmarks to figure out if |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
don't use immutable=1, only mode=ro 1426379903 | |
1295657771 | https://github.com/simonw/datasette/pull/1870#issuecomment-1295657771 | https://api.github.com/repos/simonw/datasette/issues/1870 | IC_kwDOBm6k_c5NOisr | simonw 9599 | 2022-10-29T00:19:03Z | 2022-10-29T00:19:03Z | OWNER | Just saw your comment here: https://github.com/simonw/datasette/issues/1836#issuecomment-1272357976
I don't understand this. My mental model of how Docker works is that the image itself is created using Are you saying that I can build a container, but then when I run it and it does |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
don't use immutable=1, only mode=ro 1426379903 | |
1295200988 | https://github.com/simonw/datasette/issues/1866#issuecomment-1295200988 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NMzLc | simonw 9599 | 2022-10-28T16:29:55Z | 2022-10-28T16:29:55Z | OWNER | I wonder if there's something clever I could do here within a transaction? Start a transaction. Write out a temporary in-memory table with all of the existing primary keys in the table. Run the bulk insert. Then run I don't think that's going to work well for large tables. I'm going to go with not returning inserted rows by default, unless you pass a special option requesting that. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1294316640 | https://github.com/simonw/datasette/issues/1866#issuecomment-1294316640 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NJbRg | simonw 9599 | 2022-10-28T01:51:40Z | 2022-10-28T01:51:40Z | OWNER | This needs to support the following: - Rows do not include a primary key - one is assigned by the database - Rows provide their own primary key, any clashes are errors - Rows provide their own primary key, clashes are silently ignored - Rows provide their own primary key, replacing any existing records |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1294306071 | https://github.com/simonw/datasette/issues/1866#issuecomment-1294306071 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NJYsX | simonw 9599 | 2022-10-28T01:37:14Z | 2022-10-28T01:37:59Z | OWNER | Quick crude benchmark: ```python import sqlite3 db = sqlite3.connect(":memory:") def create_table(db, name): db.execute(f"create table {name} (id integer primary key, title text)") create_table(db, "single") create_table(db, "multi") create_table(db, "bulk") def insert_singles(titles): inserted = [] for title in titles: cursor = db.execute(f"insert into single (title) values (?)", [title]) inserted.append((cursor.lastrowid, title)) return inserted def insert_many(titles): db.executemany(f"insert into multi (title) values (?)", ((t,) for t in titles)) def insert_bulk(titles): db.execute("insert into bulk (title) values {}".format( ", ".join("(?)" for _ in titles) ), titles) titles = ["title {}".format(i) for i in range(1, 10001)]
In [13]: %timeit insert_many(titles) 12 ms ± 520 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) In [12]: %timeit insert_bulk(titles) 2.59 ms ± 25 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) ``` So the bulk insert really is a lot faster - 3ms compared to 24ms for single inserts, so ~8x faster. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1294296767 | https://github.com/simonw/datasette/issues/1866#issuecomment-1294296767 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NJWa_ | simonw 9599 | 2022-10-28T01:22:25Z | 2022-10-28T01:23:09Z | OWNER | Nasty catch on this one: I wanted to return the IDs of the freshly inserted rows. But... the SQLite itself added a Two options then:
That third option might be the way to go here. I should benchmark first to figure out how much of a difference this actually makes. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1294282263 | https://github.com/simonw/datasette/issues/1866#issuecomment-1294282263 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NJS4X | simonw 9599 | 2022-10-28T01:00:42Z | 2022-10-28T01:00:42Z | OWNER | I'm going to set the limit at 1,000 rows inserted at a time. I'll make this configurable using a new |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1294281451 | https://github.com/simonw/datasette/issues/1851#issuecomment-1294281451 | https://api.github.com/repos/simonw/datasette/issues/1851 | IC_kwDOBm6k_c5NJSrr | simonw 9599 | 2022-10-28T00:59:25Z | 2022-10-28T00:59:25Z | OWNER | I'm going to use this endpoint for bulk inserts too, so I'm closing this issue and continuing the work here: - #1866 |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to insert a single record into an existing table 1421544654 | |
1289712350 | https://github.com/simonw/datasette/issues/1851#issuecomment-1289712350 | https://api.github.com/repos/simonw/datasette/issues/1851 | IC_kwDOBm6k_c5M33Le | simonw 9599 | 2022-10-24T22:28:39Z | 2022-10-27T23:18:48Z | OWNER | API design: (**UPDATE: this was later changed to POST /db/table/-/insert)
I decided to use |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to insert a single record into an existing table 1421544654 | |
1294181485 | https://github.com/simonw/datasette/issues/1869#issuecomment-1294181485 | https://api.github.com/repos/simonw/datasette/issues/1869 | IC_kwDOBm6k_c5NI6Rt | simonw 9599 | 2022-10-27T22:24:37Z | 2022-10-27T22:24:37Z | OWNER | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Release 0.63 1426253476 | ||
1294116493 | https://github.com/simonw/datasette/issues/1786#issuecomment-1294116493 | https://api.github.com/repos/simonw/datasette/issues/1786 | IC_kwDOBm6k_c5NIqaN | simonw 9599 | 2022-10-27T21:50:12Z | 2022-10-27T21:50:12Z | OWNER | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Adjust height of textarea for no JS case 1342430983 | ||
1294105558 | https://github.com/simonw/datasette/issues/1869#issuecomment-1294105558 | https://api.github.com/repos/simonw/datasette/issues/1869 | IC_kwDOBm6k_c5NInvW | simonw 9599 | 2022-10-27T21:44:13Z | 2022-10-27T21:44:13Z | OWNER | I'm going to do annotated release notes for this one. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Release 0.63 1426253476 | |
1294056552 | https://github.com/simonw/datasette/issues/1869#issuecomment-1294056552 | https://api.github.com/repos/simonw/datasette/issues/1869 | IC_kwDOBm6k_c5NIbxo | simonw 9599 | 2022-10-27T21:00:02Z | 2022-10-27T21:02:25Z | OWNER | Those release notes as markdown: Features
Plugin hooks and internals
Documentation
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Release 0.63 1426253476 | |
1294049178 | https://github.com/simonw/datasette/pull/1835#issuecomment-1294049178 | https://api.github.com/repos/simonw/datasette/issues/1835 | IC_kwDOBm6k_c5NIZ-a | simonw 9599 | 2022-10-27T20:51:30Z | 2022-10-27T20:51:30Z | OWNER | See also: - https://github.com/simonw/datasette/pull/1837 |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
use inspect data for hash and file size 1400121355 | |
1294048849 | https://github.com/simonw/datasette/pull/1837#issuecomment-1294048849 | https://api.github.com/repos/simonw/datasette/issues/1837 | IC_kwDOBm6k_c5NIZ5R | simonw 9599 | 2022-10-27T20:51:08Z | 2022-10-27T20:51:08Z | OWNER | Yeah this is better, thanks! |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make hash and size a lazy property 1400431789 | |
1294034011 | https://github.com/simonw/datasette/pull/1839#issuecomment-1294034011 | https://api.github.com/repos/simonw/datasette/issues/1839 | IC_kwDOBm6k_c5NIWRb | simonw 9599 | 2022-10-27T20:34:37Z | 2022-10-27T20:34:37Z | OWNER | @dependabot rebase |
{ "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Bump black from 22.8.0 to 22.10.0 1401155623 | |
1294012583 | https://github.com/simonw/datasette/issues/1851#issuecomment-1294012583 | https://api.github.com/repos/simonw/datasette/issues/1851 | IC_kwDOBm6k_c5NIRCn | simonw 9599 | 2022-10-27T20:11:22Z | 2022-10-27T20:11:22Z | OWNER | And the response to |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to insert a single record into an existing table 1421544654 | |
1294012084 | https://github.com/simonw/datasette/issues/1851#issuecomment-1294012084 | https://api.github.com/repos/simonw/datasette/issues/1851 | IC_kwDOBm6k_c5NIQ60 | simonw 9599 | 2022-10-27T20:10:47Z | 2022-10-27T20:10:47Z | OWNER | I'm going to change the incoming JSON back to |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to insert a single record into an existing table 1421544654 | |
1294009354 | https://github.com/simonw/datasette/issues/1851#issuecomment-1294009354 | https://api.github.com/repos/simonw/datasette/issues/1851 | IC_kwDOBm6k_c5NIQQK | simonw 9599 | 2022-10-27T20:07:42Z | 2022-10-27T20:07:42Z | OWNER | Need to implement the new URL design from: - #1868 This is now going to be |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to insert a single record into an existing table 1421544654 | |
1294008733 | https://github.com/simonw/datasette/issues/1868#issuecomment-1294008733 | https://api.github.com/repos/simonw/datasette/issues/1868 | IC_kwDOBm6k_c5NIQGd | simonw 9599 | 2022-10-27T20:07:01Z | 2022-10-27T20:07:01Z | OWNER | I'm happy with this |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Design URLs for the write API 1426195437 | |
1294008282 | https://github.com/simonw/datasette/issues/1868#issuecomment-1294008282 | https://api.github.com/repos/simonw/datasette/issues/1868 | IC_kwDOBm6k_c5NIP_a | simonw 9599 | 2022-10-27T20:06:34Z | 2022-10-27T20:06:34Z | OWNER | I'm going to stick with one |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Design URLs for the write API 1426195437 | |
1294007024 | https://github.com/simonw/datasette/issues/1868#issuecomment-1294007024 | https://api.github.com/repos/simonw/datasette/issues/1868 | IC_kwDOBm6k_c5NIPrw | simonw 9599 | 2022-10-27T20:05:44Z | 2022-10-27T20:05:52Z | OWNER | So given this scheme, the URL design would look like this:
And for rows (
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Design URLs for the write API 1426195437 | |
1294004308 | https://github.com/simonw/datasette/issues/1868#issuecomment-1294004308 | https://api.github.com/repos/simonw/datasette/issues/1868 | IC_kwDOBm6k_c5NIPBU | simonw 9599 | 2022-10-27T20:03:08Z | 2022-10-27T20:03:08Z | OWNER | The other option here would be to lean into custom HTTP verbs like |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Design URLs for the write API 1426195437 | |
1294003701 | https://github.com/simonw/datasette/issues/1868#issuecomment-1294003701 | https://api.github.com/repos/simonw/datasette/issues/1868 | IC_kwDOBm6k_c5NIO31 | simonw 9599 | 2022-10-27T20:02:26Z | 2022-10-27T20:02:26Z | OWNER | The problem with the above design is that I want to support a bunch of different actions that can be taken against a table: - insert a single row - insert multiple rows - bulk update rows - rename table - alter table - drop table I could have ALL of those be a
This is already slightly confusing in that So I'm ready to consider other design options. Initial thoughts on possible designs (for the single row insert case, but could be expanded to cover other verbs):
I quite like that third one: it feels consistent with the existing There's one slight confusion here in that it overlaps with the URL for a row with a primary key of Especially if I say that child pages of rows must theselves use the
So a row with primary key |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Design URLs for the write API 1426195437 | |
1293996735 | https://github.com/simonw/datasette/issues/1851#issuecomment-1293996735 | https://api.github.com/repos/simonw/datasette/issues/1851 | IC_kwDOBm6k_c5NINK_ | simonw 9599 | 2022-10-27T19:54:53Z | 2022-10-27T19:54:53Z | OWNER | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to insert a single record into an existing table 1421544654 | ||
1292997608 | https://github.com/simonw/datasette/issues/1851#issuecomment-1292997608 | https://api.github.com/repos/simonw/datasette/issues/1851 | IC_kwDOBm6k_c5NEZPo | simonw 9599 | 2022-10-27T04:54:53Z | 2022-10-27T19:05:50Z | OWNER | I'm going to change the design of this to:
This will be consistent with adding The API response will look like this:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to insert a single record into an existing table 1421544654 | |
1293939737 | https://github.com/simonw/datasette/issues/1860#issuecomment-1293939737 | https://api.github.com/repos/simonw/datasette/issues/1860 | IC_kwDOBm6k_c5NH_QZ | simonw 9599 | 2022-10-27T18:57:37Z | 2022-10-27T18:57:37Z | OWNER | The new code is now live at https://latest.datasette.io/fixtures |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
SQL query field can't begin by a comment 1424378012 | |
1293928738 | https://github.com/simonw/datasette/issues/1860#issuecomment-1293928738 | https://api.github.com/repos/simonw/datasette/issues/1860 | IC_kwDOBm6k_c5NH8ki | simonw 9599 | 2022-10-27T18:46:31Z | 2022-10-27T18:46:31Z | OWNER | I think mine has a better pattern for handling |
{ "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
SQL query field can't begin by a comment 1424378012 | |
1293928230 | https://github.com/simonw/datasette/issues/1860#issuecomment-1293928230 | https://api.github.com/repos/simonw/datasette/issues/1860 | IC_kwDOBm6k_c5NH8cm | simonw 9599 | 2022-10-27T18:46:03Z | 2022-10-27T18:46:03Z | OWNER | Here's yours on Debuggex: https://www.debuggex.com/r/HjdJryTy9ezGsuWK |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
SQL query field can't begin by a comment 1424378012 | |
1293926417 | https://github.com/simonw/datasette/issues/1860#issuecomment-1293926417 | https://api.github.com/repos/simonw/datasette/issues/1860 | IC_kwDOBm6k_c5NH8AR | simonw 9599 | 2022-10-27T18:44:20Z | 2022-10-27T18:45:21Z | OWNER | Hah, I just came up with this one - we were clearly working on this at the same time!
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
SQL query field can't begin by a comment 1424378012 | |
1293893789 | https://github.com/simonw/datasette/issues/1866#issuecomment-1293893789 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NH0Cd | simonw 9599 | 2022-10-27T18:13:00Z | 2022-10-27T18:13:00Z | OWNER | If people care about that kind of thing they could always push all of their inserts to a table called |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1293892818 | https://github.com/simonw/datasette/issues/1866#issuecomment-1293892818 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NHzzS | simonw 9599 | 2022-10-27T18:12:02Z | 2022-10-27T18:12:02Z | OWNER | There's one catch with batched inserts: if your CLI tool fails half way through you could end up with a partially populated table - since a bunch of batches will have succeeded first. I think that's OK. In the future I may want to come up with a way to run multiple batches of inserts inside a single transaction, but I can ignore that for the first release of this feature. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1293891876 | https://github.com/simonw/datasette/issues/1866#issuecomment-1293891876 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NHzkk | simonw 9599 | 2022-10-27T18:11:05Z | 2022-10-27T18:11:05Z | OWNER | Likewise for newline-delimited JSON. While it's tempting to want to accept that as an ingest format (because it's nice to generate and stream) I think it's better to have a client application that can turn a stream of newline-delimited JSON into batched JSON inserts. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1293891191 | https://github.com/simonw/datasette/issues/1866#issuecomment-1293891191 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NHzZ3 | simonw 9599 | 2022-10-27T18:10:22Z | 2022-10-27T18:10:22Z | OWNER | So for the moment I'm just going to concentrate on the JSON API. I can consider CSV variants later on, or as plugins, or both. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1293890684 | https://github.com/simonw/datasette/issues/1866#issuecomment-1293890684 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NHzR8 | simonw 9599 | 2022-10-27T18:09:52Z | 2022-10-27T18:09:52Z | OWNER | Should this API accept CSV/TSV etc in addition to JSON? I'm torn on this one. My initial instinct is that it should not - and there should instead be a Datasette client library / CLI tool you can use that knows how to turn CSV into batches of JSON calls for when you want to upload a CSV file. I don't think the usability of |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1293887808 | https://github.com/simonw/datasette/issues/1866#issuecomment-1293887808 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NHylA | simonw 9599 | 2022-10-27T18:07:02Z | 2022-10-27T18:07:02Z | OWNER | Error handling is really important here. What should happen if you submit 100 records and one of them has some kind of validation error? How should that error be reported back to you? I'm inclined to say that it defaults to all-or-nothing in a transaction - but there should be a |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1293857306 | https://github.com/simonw/datasette/issues/1862#issuecomment-1293857306 | https://api.github.com/repos/simonw/datasette/issues/1862 | IC_kwDOBm6k_c5NHrIa | simonw 9599 | 2022-10-27T17:38:17Z | 2022-10-27T17:38:17Z | OWNER | Strongly related to: - #1866 |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Create a new table from one or more records, `sqlite-utils` style 1425011030 | |
1293568194 | https://github.com/simonw/datasette/issues/1865#issuecomment-1293568194 | https://api.github.com/repos/simonw/datasette/issues/1865 | IC_kwDOBm6k_c5NGkjC | simonw 9599 | 2022-10-27T13:58:26Z | 2022-10-27T13:58:26Z | OWNER | Here's the issue where I started doing this: - #849 |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Stop syncing main to master 1425682079 | |
649908756 | https://github.com/simonw/datasette/issues/849#issuecomment-649908756 | https://api.github.com/repos/simonw/datasette/issues/849 | MDEyOklzc3VlQ29tbWVudDY0OTkwODc1Ng== | simonw 9599 | 2020-06-26T02:09:09Z | 2022-10-27T13:57:08Z | OWNER | I mentioned this issue here: https://simonwillison.net/2020/Jun/26/weeknotes-plugins-sqlite-generate/ Repositories created by following the README in https://github.com/simonw/datasette-template and https://github.com/simonw/click-app have a |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Rename master branch to main 639072811 | |
1292999579 | https://github.com/simonw/datasette/issues/1851#issuecomment-1292999579 | https://api.github.com/repos/simonw/datasette/issues/1851 | IC_kwDOBm6k_c5NEZub | simonw 9599 | 2022-10-27T04:59:06Z | 2022-10-27T04:59:12Z | OWNER | I should probably refactor this to use Might make it easier to solve the rowid issues too. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to insert a single record into an existing table 1421544654 | |
1292996181 | https://github.com/simonw/datasette/issues/1851#issuecomment-1292996181 | https://api.github.com/repos/simonw/datasette/issues/1851 | IC_kwDOBm6k_c5NEY5V | simonw 9599 | 2022-10-27T04:51:47Z | 2022-10-27T04:51:47Z | OWNER | Also need a test for invalid JSON (currently triggers a 500 HTML error). |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to insert a single record into an existing table 1421544654 | |
1292962813 | https://github.com/simonw/datasette/issues/1855#issuecomment-1292962813 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5NEQv9 | simonw 9599 | 2022-10-27T04:31:40Z | 2022-10-27T04:31:40Z | OWNER | My hunch on this is that anyone with that level of complex permissions requirements needs to be using a custom authentication plugin which includes much more concrete token rules, rather than the default signed stateless token implementation that ships with Datasette core. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1292959886 | https://github.com/simonw/datasette/issues/1855#issuecomment-1292959886 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5NEQCO | simonw 9599 | 2022-10-27T04:30:07Z | 2022-10-27T04:30:07Z | OWNER | Here's an interesting edge-case to consider: what if a user creates themselves a token for a specific table, then deletes that table, and waits for another user to create a table of the same name... and then uses their previously created token to write to the table that someone else created? Not sure if this is a threat I need to actively consider, but it's worth thinking a little bit about the implications of such a thing - since there will be APIs that allow users to create tables, and there may be cases where people want to have a concept of users "owning" specific tables. This is probably something that could be left for plugins to solve, but it still needs to be understood and potentially documented. There may even be a world in which tracking the timestamp at which a table was created becomes useful - because that could then be baked into API tokens, such that a token created BEFORE the table was created does not grant access to that table. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1292952121 | https://github.com/simonw/datasette/issues/1851#issuecomment-1292952121 | https://api.github.com/repos/simonw/datasette/issues/1851 | IC_kwDOBm6k_c5NEOI5 | simonw 9599 | 2022-10-27T04:24:09Z | 2022-10-27T04:24:20Z | OWNER | And come up with a whole bunch of tests for weird table shapes, surprising column names, different types etc. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to insert a single record into an existing table 1421544654 | |
1292951833 | https://github.com/simonw/datasette/issues/1851#issuecomment-1292951833 | https://api.github.com/repos/simonw/datasette/issues/1851 | IC_kwDOBm6k_c5NEOEZ | simonw 9599 | 2022-10-27T04:23:40Z | 2022-10-27T04:23:40Z | OWNER | Also need to think about transactions - it should use them! |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to insert a single record into an existing table 1421544654 | |
1292939146 | https://github.com/simonw/datasette/issues/1851#issuecomment-1292939146 | https://api.github.com/repos/simonw/datasette/issues/1851 | IC_kwDOBm6k_c5NEK-K | simonw 9599 | 2022-10-27T04:00:17Z | 2022-10-27T04:23:15Z | OWNER | Documentation for this first draft of the API: https://docs.datasette.io/en/1.0-dev/json_api.html#inserting-a-single-row It currently returns errors as HTML - it needs to return errors as JSON. Also the errors need comprehensive test coverage. I'm also worried about what happens if you use it on a table that doesn't use an integer primary key - need to check that. I think this code may break: Plus will |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to insert a single record into an existing table 1421544654 | |
1292940011 | https://github.com/simonw/datasette/issues/1850#issuecomment-1292940011 | https://api.github.com/repos/simonw/datasette/issues/1850 | IC_kwDOBm6k_c5NELLr | simonw 9599 | 2022-10-27T04:01:59Z | 2022-10-27T04:01:59Z | OWNER | Working on that first "insert row" implementation: Has made it very clear to me that I should go the whole hog and build the basic form-based interface for this as well. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Write API in Datasette core 1421529723 | |
1292709818 | https://github.com/simonw/datasette/issues/1858#issuecomment-1292709818 | https://api.github.com/repos/simonw/datasette/issues/1858 | IC_kwDOBm6k_c5NDS-6 | simonw 9599 | 2022-10-26T22:07:04Z | 2022-10-26T22:07:04Z | OWNER | New token design:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`max_signed_tokens_ttl` setting for a maximum duration on API tokens 1423364990 | |
1292708227 | https://github.com/simonw/datasette/issues/1858#issuecomment-1292708227 | https://api.github.com/repos/simonw/datasette/issues/1858 | IC_kwDOBm6k_c5NDSmD | simonw 9599 | 2022-10-26T22:05:34Z | 2022-10-26T22:05:34Z | OWNER | I just realized this can't easily affect the More to the point: even if it did, someone could abuse their knowledge of the secret to create a signed non-expiring token even on servers that didn't want to support those. So I actually need to redesign the token format: it needs to store the timestamp when the token was created and the intended duration, NOT the timestamp that the token expires at. Otherwise it's not possible for servers to enforce |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`max_signed_tokens_ttl` setting for a maximum duration on API tokens 1423364990 |
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