Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

?_where=sql-fragment parameter for table views #429

Closed
simonw opened this issue Apr 12, 2019 · 7 comments
Closed

?_where=sql-fragment parameter for table views #429

simonw opened this issue Apr 12, 2019 · 7 comments

Comments

@simonw
Copy link
Owner

simonw commented Apr 12, 2019

Only available if arbitrary SQL is enabled (the default).

?_where=id in (1,2,3)&_where=id in (select tag_id from tags)

Allows any table (or view) page to have arbitrary additional extra_where clauses defined using the URL!

This would be extremely useful for building JavaScript applications against the Datasette API that only need on extra tiny bit of SQL but still want to benefit from other table view features like faceting.

Would be nice if this could take :named parameters and have them filled in via querystring as well.

@simonw
Copy link
Owner Author

simonw commented Apr 12, 2019

I originally thought of this as a plugin but then realized that it's 100% compatible with Datasette's existing arbitrary SQL clauses and would make some of my other projects (especially involving custom queries that still need faceting) a whole lot easier.

@simonw
Copy link
Owner Author

simonw commented Apr 12, 2019

Getting a prototype working was hardly any code at all:

http://127.0.0.1:8001/fixtures/facetable?_where=city_id+in+(select+id+from+facet_cities+where+name+like+%22%25an%25%22)

diff --git a/datasette/views/table.py b/datasette/views/table.py
index b7c9a4b..7ca9572 100644
--- a/datasette/views/table.py
+++ b/datasette/views/table.py
@@ -295,6 +295,10 @@ class TableView(RowTableShared):
         filters = Filters(sorted(other_args.items()), units, ureg)
         where_clauses, params = filters.build_where_clauses(table)
 
+        # Add _where= from querystring
+        if self.ds.config("allow_sql") and "_where" in request.args:
+            where_clauses.extend(request.args["_where"])
+
         # _search support:
         fts_table = special_args.get("_fts_table")
         fts_table = fts_table or table_metadata.get("fts_table")

Still needed:

  • Unit tests
  • Probably some kind of visual display on the table page so you know that extra clauses have been added (and maybe a UI for dropping them again)

I'm going to leave the :named parameter support out of the first version of this feature.

@simonw
Copy link
Owner Author

simonw commented Apr 12, 2019

UI concept:

fixtures__facetable__10_rows

<h3>1 extra where clause:</h3>
<p><code>city_id in (select id from facet_cities where name like "%an%")</code> [<a href="#">remove</a>]</p>

@simonw
Copy link
Owner Author

simonw commented Apr 12, 2019

Keeping track of these and building the "remove" links correctly is going to be a tiny bit fiddly.

@simonw
Copy link
Owner Author

simonw commented Apr 12, 2019

Maybe put this section above the "view and edit SQL" link.

simonw added a commit that referenced this issue Apr 12, 2019
simonw added a commit that referenced this issue Apr 13, 2019
simonw added a commit that referenced this issue Apr 13, 2019
@simonw simonw closed this as completed in bc6a9b4 Apr 13, 2019
@psychemedia
Copy link
Contributor

Minor UI observation:

image

_where= renders a [remove] link whereas _facet= gets a cross to remove it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants