Applied sphinx-inline-tabs to remaining examples, refs #1153

pull/2099/head
Simon Willison 2023-07-08 11:00:08 -07:00
rodzic 0183e1a72d
commit c076fb65e0
8 zmienionych plików z 1019 dodań i 152 usunięć

Wyświetl plik

@ -212,23 +212,63 @@ Access to an instance
Here's how to restrict access to your entire Datasette instance to just the ``"id": "root"`` user:
.. code-block:: json
{
.. [[[cog
from metadata_doc import metadata_example
metadata_example(cog, {
"title": "My private Datasette instance",
"allow": {
"id": "root"
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
title: My private Datasette instance
allow:
id: root
.. tab:: JSON
.. code-block:: json
{
"title": "My private Datasette instance",
"allow": {
"id": "root"
}
}
.. [[[end]]]
To deny access to all users, you can use ``"allow": false``:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"title": "My entirely inaccessible instance",
"allow": false
}
"allow": False
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
title: My entirely inaccessible instance
allow: false
.. tab:: JSON
.. code-block:: json
{
"title": "My entirely inaccessible instance",
"allow": false
}
.. [[[end]]]
One reason to do this is if you are using a Datasette plugin - such as `datasette-permissions-sql <https://github.com/simonw/datasette-permissions-sql>`__ - to control permissions instead.
@ -239,9 +279,8 @@ Access to specific databases
To limit access to a specific ``private.db`` database to just authenticated users, use the ``"allow"`` block like this:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"databases": {
"private": {
"allow": {
@ -249,7 +288,33 @@ To limit access to a specific ``private.db`` database to just authenticated user
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
databases:
private:
allow:
id: '*'
.. tab:: JSON
.. code-block:: json
{
"databases": {
"private": {
"allow": {
"id": "*"
}
}
}
}
.. [[[end]]]
.. _authentication_permissions_table:
@ -258,9 +323,8 @@ Access to specific tables and views
To limit access to the ``users`` table in your ``bakery.db`` database:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"databases": {
"bakery": {
"tables": {
@ -272,7 +336,39 @@ To limit access to the ``users`` table in your ``bakery.db`` database:
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
databases:
bakery:
tables:
users:
allow:
id: '*'
.. tab:: JSON
.. code-block:: json
{
"databases": {
"bakery": {
"tables": {
"users": {
"allow": {
"id": "*"
}
}
}
}
}
}
.. [[[end]]]
This works for SQL views as well - you can list their names in the ``"tables"`` block above in the same way as regular tables.
@ -290,15 +386,14 @@ Access to specific canned queries
To limit access to the ``add_name`` canned query in your ``dogs.db`` database to just the :ref:`root user<authentication_root>`:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"databases": {
"dogs": {
"queries": {
"add_name": {
"sql": "INSERT INTO names (name) VALUES (:name)",
"write": true,
"write": True,
"allow": {
"id": ["root"]
}
@ -306,7 +401,46 @@ To limit access to the ``add_name`` canned query in your ``dogs.db`` database to
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
databases:
dogs:
queries:
add_name:
sql: INSERT INTO names (name) VALUES (:name)
write: true
allow:
id:
- root
.. tab:: JSON
.. code-block:: json
{
"databases": {
"dogs": {
"queries": {
"add_name": {
"sql": "INSERT INTO names (name) VALUES (:name)",
"write": true,
"allow": {
"id": [
"root"
]
}
}
}
}
}
}
.. [[[end]]]
.. _authentication_permissions_execute_sql:
@ -323,27 +457,61 @@ You can alternatively use an ``"allow_sql"`` block to control who is allowed to
To prevent any user from executing arbitrary SQL queries, use this:
.. code-block:: json
.. [[[cog
metadata_example(cog, {
"allow_sql": False
})
.. ]]]
{
"allow_sql": false
}
.. tab:: YAML
.. code-block:: yaml
allow_sql: false
.. tab:: JSON
.. code-block:: json
{
"allow_sql": false
}
.. [[[end]]]
To enable just the :ref:`root user<authentication_root>` to execute SQL for all databases in your instance, use the following:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"allow_sql": {
"id": "root"
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
allow_sql:
id: root
.. tab:: JSON
.. code-block:: json
{
"allow_sql": {
"id": "root"
}
}
.. [[[end]]]
To limit this ability for just one specific database, use this:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"databases": {
"mydatabase": {
"allow_sql": {
@ -351,7 +519,33 @@ To limit this ability for just one specific database, use this:
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
databases:
mydatabase:
allow_sql:
id: root
.. tab:: JSON
.. code-block:: json
{
"databases": {
"mydatabase": {
"allow_sql": {
"id": "root"
}
}
}
}
.. [[[end]]]
.. _authentication_permissions_other:
@ -362,21 +556,42 @@ For all other permissions, you can use one or more ``"permissions"`` blocks in y
To grant access to the :ref:`permissions debug tool <PermissionsDebugView>` to all signed in users you can grant ``permissions-debug`` to any actor with an ``id`` matching the wildcard ``*`` by adding this a the root of your metadata:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"permissions": {
"debug-menu": {
"id": "*"
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
permissions:
debug-menu:
id: '*'
.. tab:: JSON
.. code-block:: json
{
"permissions": {
"debug-menu": {
"id": "*"
}
}
}
.. [[[end]]]
To grant ``create-table`` to the user with ``id`` of ``editor`` for the ``docs`` database:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"databases": {
"docs": {
"permissions": {
@ -386,13 +601,41 @@ To grant ``create-table`` to the user with ``id`` of ``editor`` for the ``docs``
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
databases:
docs:
permissions:
create-table:
id: editor
.. tab:: JSON
.. code-block:: json
{
"databases": {
"docs": {
"permissions": {
"create-table": {
"id": "editor"
}
}
}
}
}
.. [[[end]]]
And for ``insert-row`` against the ``reports`` table in that ``docs`` database:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"databases": {
"docs": {
"tables": {
@ -406,7 +649,42 @@ And for ``insert-row`` against the ``reports`` table in that ``docs`` database:
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
databases:
docs:
tables:
reports:
permissions:
insert-row:
id: editor
.. tab:: JSON
.. code-block:: json
{
"databases": {
"docs": {
"tables": {
"reports": {
"permissions": {
"insert-row": {
"id": "editor"
}
}
}
}
}
}
}
.. [[[end]]]
The :ref:`permissions debug tool <PermissionsDebugView>` can be useful for helping test permissions that you have configured in this way.

Wyświetl plik

@ -12,20 +12,45 @@ Custom CSS and JavaScript
When you launch Datasette, you can specify a custom metadata file like this::
datasette mydb.db --metadata metadata.json
datasette mydb.db --metadata metadata.yaml
Your ``metadata.json`` file can include links that look like this:
Your ``metadata.yaml`` file can include links that look like this:
.. code-block:: json
{
.. [[[cog
from metadata_doc import metadata_example
metadata_example(cog, {
"extra_css_urls": [
"https://simonwillison.net/static/css/all.bf8cd891642c.css"
],
"extra_js_urls": [
"https://code.jquery.com/jquery-3.2.1.slim.min.js"
]
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
extra_css_urls:
- https://simonwillison.net/static/css/all.bf8cd891642c.css
extra_js_urls:
- https://code.jquery.com/jquery-3.2.1.slim.min.js
.. tab:: JSON
.. code-block:: json
{
"extra_css_urls": [
"https://simonwillison.net/static/css/all.bf8cd891642c.css"
],
"extra_js_urls": [
"https://code.jquery.com/jquery-3.2.1.slim.min.js"
]
}
.. [[[end]]]
The extra CSS and JavaScript files will be linked in the ``<head>`` of every page:
@ -36,9 +61,8 @@ The extra CSS and JavaScript files will be linked in the ``<head>`` of every pag
You can also specify a SRI (subresource integrity hash) for these assets:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"extra_css_urls": [
{
"url": "https://simonwillison.net/static/css/all.bf8cd891642c.css",
@ -51,7 +75,40 @@ You can also specify a SRI (subresource integrity hash) for these assets:
"sri": "sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
}
]
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
extra_css_urls:
- url: https://simonwillison.net/static/css/all.bf8cd891642c.css
sri: sha384-9qIZekWUyjCyDIf2YK1FRoKiPJq4PHt6tp/ulnuuyRBvazd0hG7pWbE99zvwSznI
extra_js_urls:
- url: https://code.jquery.com/jquery-3.2.1.slim.min.js
sri: sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g=
.. tab:: JSON
.. code-block:: json
{
"extra_css_urls": [
{
"url": "https://simonwillison.net/static/css/all.bf8cd891642c.css",
"sri": "sha384-9qIZekWUyjCyDIf2YK1FRoKiPJq4PHt6tp/ulnuuyRBvazd0hG7pWbE99zvwSznI"
}
],
"extra_js_urls": [
{
"url": "https://code.jquery.com/jquery-3.2.1.slim.min.js",
"sri": "sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
}
]
}
.. [[[end]]]
This will produce:
@ -69,16 +126,39 @@ matches the content served. You can generate hashes using `www.srihash.org <http
Items in ``"extra_js_urls"`` can specify ``"module": true`` if they reference JavaScript that uses `JavaScript modules <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules>`__. This configuration:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"extra_js_urls": [
{
"url": "https://example.datasette.io/module.js",
"module": true
"module": True
}
]
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
extra_js_urls:
- url: https://example.datasette.io/module.js
module: true
.. tab:: JSON
.. code-block:: json
{
"extra_js_urls": [
{
"url": "https://example.datasette.io/module.js",
"module": true
}
]
}
.. [[[end]]]
Will produce this HTML:
@ -188,16 +268,40 @@ The following URLs will now serve the content from those CSS and JS files::
You can reference those files from ``metadata.json`` like so:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"extra_css_urls": [
"/assets/styles.css"
],
"extra_js_urls": [
"/assets/app.js"
]
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
extra_css_urls:
- /assets/styles.css
extra_js_urls:
- /assets/app.js
.. tab:: JSON
.. code-block:: json
{
"extra_css_urls": [
"/assets/styles.css"
],
"extra_js_urls": [
"/assets/app.js"
]
}
.. [[[end]]]
Publishing static assets
~~~~~~~~~~~~~~~~~~~~~~~~

Wyświetl plik

@ -98,16 +98,16 @@ You can increase this on an individual page by adding ``?_facet_size=100`` to th
.. _facets_metadata:
Facets in metadata.json
-----------------------
Facets in metadata
------------------
You can turn facets on by default for specific tables by adding them to a ``"facets"`` key in a Datasette :ref:`metadata` file.
Here's an example that turns on faceting by default for the ``qLegalStatus`` column in the ``Street_Tree_List`` table in the ``sf-trees`` database:
.. code-block:: json
{
.. [[[cog
from metadata_doc import metadata_example
metadata_example(cog, {
"databases": {
"sf-trees": {
"tables": {
@ -117,26 +117,82 @@ Here's an example that turns on faceting by default for the ``qLegalStatus`` col
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
databases:
sf-trees:
tables:
Street_Tree_List:
facets:
- qLegalStatus
.. tab:: JSON
.. code-block:: json
{
"databases": {
"sf-trees": {
"tables": {
"Street_Tree_List": {
"facets": [
"qLegalStatus"
]
}
}
}
}
}
.. [[[end]]]
Facets defined in this way will always be shown in the interface and returned in the API, regardless of the ``_facet`` arguments passed to the view.
You can specify :ref:`array <facet_by_json_array>` or :ref:`date <facet_by_date>` facets in metadata using JSON objects with a single key of ``array`` or ``date`` and a value specifying the column, like this:
.. code-block:: json
.. [[[cog
metadata_example(cog, {
"facets": [
{"array": "tags"},
{"date": "created"}
]
})
.. ]]]
{
"facets": [
{"array": "tags"},
{"date": "created"}
]
}
.. tab:: YAML
.. code-block:: yaml
facets:
- array: tags
- date: created
.. tab:: JSON
.. code-block:: json
{
"facets": [
{
"array": "tags"
},
{
"date": "created"
}
]
}
.. [[[end]]]
You can change the default facet size (the number of results shown for each facet) for a table using ``facet_size``:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"databases": {
"sf-trees": {
"tables": {
@ -147,7 +203,41 @@ You can change the default facet size (the number of results shown for each face
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
databases:
sf-trees:
tables:
Street_Tree_List:
facets:
- qLegalStatus
facet_size: 10
.. tab:: JSON
.. code-block:: json
{
"databases": {
"sf-trees": {
"tables": {
"Street_Tree_List": {
"facets": [
"qLegalStatus"
],
"facet_size": 10
}
}
}
}
}
.. [[[end]]]
Suggested facets
----------------

Wyświetl plik

@ -64,9 +64,9 @@ The ``"searchmode": "raw"`` property can be used to default the table to accepti
Here is an example which enables full-text search (with SQLite advanced search operators) for a ``display_ads`` view which is defined against the ``ads`` table and hence needs to run FTS against the ``ads_fts`` table, using the ``id`` as the primary key:
.. code-block:: json
{
.. [[[cog
from metadata_doc import metadata_example
metadata_example(cog, {
"databases": {
"russian-ads": {
"tables": {
@ -78,7 +78,40 @@ Here is an example which enables full-text search (with SQLite advanced search o
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
databases:
russian-ads:
tables:
display_ads:
fts_table: ads_fts
fts_pk: id
searchmode: raw
.. tab:: JSON
.. code-block:: json
{
"databases": {
"russian-ads": {
"tables": {
"display_ads": {
"fts_table": "ads_fts",
"fts_pk": "id",
"searchmode": "raw"
}
}
}
}
}
.. [[[end]]]
.. _full_text_search_custom_sql:

Wyświetl plik

@ -1,13 +1,25 @@
import json
import textwrap
import yaml
from yaml import safe_dump
from ruamel.yaml import round_trip_load
def metadata_example(cog, example):
def metadata_example(cog, data=None, yaml=None):
assert data or yaml, "Must provide data= or yaml="
assert not (data and yaml), "Cannot use data= and yaml="
output_yaml = None
if yaml:
# dedent it first
yaml = textwrap.dedent(yaml).strip()
# round_trip_load to preserve key order:
data = round_trip_load(yaml)
output_yaml = yaml
else:
output_yaml = safe_dump(data, sort_keys=False)
cog.out("\n.. tab:: YAML\n\n")
cog.out(" .. code-block:: yaml\n\n")
cog.out(textwrap.indent(yaml.safe_dump(example, sort_keys=False), " "))
cog.out(textwrap.indent(output_yaml, " "))
cog.out("\n\n.. tab:: JSON\n\n")
cog.out(" .. code-block:: json\n\n")
cog.out(textwrap.indent(json.dumps(example, indent=2), " "))
cog.out(textwrap.indent(json.dumps(data, indent=2), " "))
cog.out("\n")

Wyświetl plik

@ -245,9 +245,9 @@ Plugins can have their own configuration, embedded in a :ref:`metadata` file. Co
Here is an example of some plugin configuration for a specific table:
.. code-block:: json
{
.. [[[cog
from metadata_doc import metadata_example
metadata_example(cog, {
"databases": {
"sf-trees": {
"tables": {
@ -262,7 +262,44 @@ Here is an example of some plugin configuration for a specific table:
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
databases:
sf-trees:
tables:
Street_Tree_List:
plugins:
datasette-cluster-map:
latitude_column: lat
longitude_column: lng
.. tab:: JSON
.. code-block:: json
{
"databases": {
"sf-trees": {
"tables": {
"Street_Tree_List": {
"plugins": {
"datasette-cluster-map": {
"latitude_column": "lat",
"longitude_column": "lng"
}
}
}
}
}
}
}
.. [[[end]]]
This tells the ``datasette-cluster-map`` column which latitude and longitude columns should be used for a table called ``Street_Tree_List`` inside a database file called ``sf-trees.db``.
@ -271,13 +308,12 @@ This tells the ``datasette-cluster-map`` column which latitude and longitude col
Secret configuration values
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Any values embedded in ``metadata.json`` will be visible to anyone who views the ``/-/metadata`` page of your Datasette instance. Some plugins may need configuration that should stay secret - API keys for example. There are two ways in which you can store secret configuration values.
Any values embedded in ``metadata.yaml`` will be visible to anyone who views the ``/-/metadata`` page of your Datasette instance. Some plugins may need configuration that should stay secret - API keys for example. There are two ways in which you can store secret configuration values.
**As environment variables**. If your secret lives in an environment variable that is available to the Datasette process, you can indicate that the configuration value should be read from that environment variable like so:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"plugins": {
"datasette-auth-github": {
"client_secret": {
@ -285,13 +321,38 @@ Any values embedded in ``metadata.json`` will be visible to anyone who views the
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
plugins:
datasette-auth-github:
client_secret:
$env: GITHUB_CLIENT_SECRET
.. tab:: JSON
.. code-block:: json
{
"plugins": {
"datasette-auth-github": {
"client_secret": {
"$env": "GITHUB_CLIENT_SECRET"
}
}
}
}
.. [[[end]]]
**As values in separate files**. Your secrets can also live in files on disk. To specify a secret should be read from a file, provide the full file path like this:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"plugins": {
"datasette-auth-github": {
"client_secret": {
@ -299,7 +360,33 @@ Any values embedded in ``metadata.json`` will be visible to anyone who views the
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
plugins:
datasette-auth-github:
client_secret:
$file: /secrets/client-secret
.. tab:: JSON
.. code-block:: json
{
"plugins": {
"datasette-auth-github": {
"client_secret": {
"$file": "/secrets/client-secret"
}
}
}
}
.. [[[end]]]
If you are publishing your data using the :ref:`datasette publish <cli_publish>` family of commands, you can use the ``--plugin-secret`` option to set these secrets at publish time. For example, using Heroku you might run the following command::
@ -309,11 +396,10 @@ If you are publishing your data using the :ref:`datasette publish <cli_publish>`
--plugin-secret datasette-auth-github client_id your_client_id \
--plugin-secret datasette-auth-github client_secret your_client_secret
This will set the necessary environment variables and add the following to the deployed ``metadata.json``:
This will set the necessary environment variables and add the following to the deployed ``metadata.yaml``:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"plugins": {
"datasette-auth-github": {
"client_id": {
@ -324,4 +410,35 @@ This will set the necessary environment variables and add the following to the d
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
plugins:
datasette-auth-github:
client_id:
$env: DATASETTE_AUTH_GITHUB_CLIENT_ID
client_secret:
$env: DATASETTE_AUTH_GITHUB_CLIENT_SECRET
.. tab:: JSON
.. code-block:: json
{
"plugins": {
"datasette-auth-github": {
"client_id": {
"$env": "DATASETTE_AUTH_GITHUB_CLIENT_ID"
},
"client_secret": {
"$env": "DATASETTE_AUTH_GITHUB_CLIENT_SECRET"
}
}
}
}
.. [[[end]]]

Wyświetl plik

@ -64,11 +64,11 @@ The quickest way to create views is with the SQLite command-line interface::
Canned queries
--------------
As an alternative to adding views to your database, you can define canned queries inside your ``metadata.json`` file. Here's an example:
As an alternative to adding views to your database, you can define canned queries inside your ``metadata.yaml`` file. Here's an example:
.. code-block:: json
{
.. [[[cog
from metadata_doc import metadata_example
metadata_example(cog, {
"databases": {
"sf-trees": {
"queries": {
@ -78,7 +78,36 @@ As an alternative to adding views to your database, you can define canned querie
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
databases:
sf-trees:
queries:
just_species:
sql: select qSpecies from Street_Tree_List
.. tab:: JSON
.. code-block:: json
{
"databases": {
"sf-trees": {
"queries": {
"just_species": {
"sql": "select qSpecies from Street_Tree_List"
}
}
}
}
}
.. [[[end]]]
Then run Datasette like this::
@ -111,38 +140,58 @@ Here's an example of a canned query with a named parameter:
where neighborhood like '%' || :text || '%'
order by neighborhood;
In the canned query metadata (here :ref:`metadata_yaml` as ``metadata.yaml``) it looks like this:
In the canned query metadata looks like this:
.. code-block:: yaml
.. [[[cog
metadata_example(cog, yaml="""
databases:
fixtures:
queries:
neighborhood_search:
title: Search neighborhoods
sql: |-
select neighborhood, facet_cities.name, state
from facetable
join facet_cities on facetable.city_id = facet_cities.id
where neighborhood like '%' || :text || '%'
order by neighborhood
title: Search neighborhoods
""")
.. ]]]
Here's the equivalent using JSON (as ``metadata.json``):
.. tab:: YAML
.. code-block:: json
.. code-block:: yaml
{
"databases": {
databases:
fixtures:
queries:
neighborhood_search:
title: Search neighborhoods
sql: |-
select neighborhood, facet_cities.name, state
from facetable
join facet_cities on facetable.city_id = facet_cities.id
where neighborhood like '%' || :text || '%'
order by neighborhood
.. tab:: JSON
.. code-block:: json
{
"databases": {
"fixtures": {
"queries": {
"neighborhood_search": {
"sql": "select neighborhood, facet_cities.name, state\nfrom facetable\n join facet_cities on facetable.city_id = facet_cities.id\nwhere neighborhood like '%' || :text || '%'\norder by neighborhood",
"title": "Search neighborhoods"
}
"queries": {
"neighborhood_search": {
"title": "Search neighborhoods",
"sql": "select neighborhood, facet_cities.name, state\nfrom facetable\n join facet_cities on facetable.city_id = facet_cities.id\nwhere neighborhood like '%' || :text || '%'\norder by neighborhood"
}
}
}
}
}
}
.. [[[end]]]
Note that we are using SQLite string concatenation here - the ``||`` operator - to add wildcard ``%`` characters to the string provided by the user.
@ -153,12 +202,13 @@ In this example the ``:text`` named parameter is automatically extracted from th
You can alternatively provide an explicit list of named parameters using the ``"params"`` key, like this:
.. code-block:: yaml
.. [[[cog
metadata_example(cog, yaml="""
databases:
fixtures:
queries:
neighborhood_search:
title: Search neighborhoods
params:
- text
sql: |-
@ -167,7 +217,47 @@ You can alternatively provide an explicit list of named parameters using the ``"
join facet_cities on facetable.city_id = facet_cities.id
where neighborhood like '%' || :text || '%'
order by neighborhood
title: Search neighborhoods
""")
.. ]]]
.. tab:: YAML
.. code-block:: yaml
databases:
fixtures:
queries:
neighborhood_search:
title: Search neighborhoods
params:
- text
sql: |-
select neighborhood, facet_cities.name, state
from facetable
join facet_cities on facetable.city_id = facet_cities.id
where neighborhood like '%' || :text || '%'
order by neighborhood
.. tab:: JSON
.. code-block:: json
{
"databases": {
"fixtures": {
"queries": {
"neighborhood_search": {
"title": "Search neighborhoods",
"params": [
"text"
],
"sql": "select neighborhood, facet_cities.name, state\nfrom facetable\n join facet_cities on facetable.city_id = facet_cities.id\nwhere neighborhood like '%' || :text || '%'\norder by neighborhood"
}
}
}
}
}
.. [[[end]]]
.. _canned_queries_options:
@ -192,21 +282,54 @@ You can set a default fragment hash that will be included in the link to the can
This example demonstrates both ``fragment`` and ``hide_sql``:
.. code-block:: json
.. [[[cog
metadata_example(cog, yaml="""
databases:
fixtures:
queries:
neighborhood_search:
fragment: fragment-goes-here
hide_sql: true
sql: |-
select neighborhood, facet_cities.name, state
from facetable join facet_cities on facetable.city_id = facet_cities.id
where neighborhood like '%' || :text || '%' order by neighborhood;
""")
.. ]]]
{
"databases": {
.. tab:: YAML
.. code-block:: yaml
databases:
fixtures:
queries:
neighborhood_search:
fragment: fragment-goes-here
hide_sql: true
sql: |-
select neighborhood, facet_cities.name, state
from facetable join facet_cities on facetable.city_id = facet_cities.id
where neighborhood like '%' || :text || '%' order by neighborhood;
.. tab:: JSON
.. code-block:: json
{
"databases": {
"fixtures": {
"queries": {
"neighborhood_search": {
"sql": "select neighborhood, facet_cities.name, state\nfrom facetable join facet_cities on facetable.city_id = facet_cities.id\nwhere neighborhood like '%' || :text || '%' order by neighborhood;",
"fragment": "fragment-goes-here",
"hide_sql": true
}
"queries": {
"neighborhood_search": {
"fragment": "fragment-goes-here",
"hide_sql": true,
"sql": "select neighborhood, facet_cities.name, state\nfrom facetable join facet_cities on facetable.city_id = facet_cities.id\nwhere neighborhood like '%' || :text || '%' order by neighborhood;"
}
}
}
}
}
}
.. [[[end]]]
`See here <https://latest.datasette.io/fixtures#queries>`__ for a demo of this in action.
@ -219,20 +342,50 @@ Canned queries by default are read-only. You can use the ``"write": true`` key t
See :ref:`authentication_permissions_query` for details on how to add permission checks to canned queries, using the ``"allow"`` key.
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"databases": {
"mydatabase": {
"queries": {
"add_name": {
"sql": "INSERT INTO names (name) VALUES (:name)",
"write": true
"write": True
}
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
databases:
mydatabase:
queries:
add_name:
sql: INSERT INTO names (name) VALUES (:name)
write: true
.. tab:: JSON
.. code-block:: json
{
"databases": {
"mydatabase": {
"queries": {
"add_name": {
"sql": "INSERT INTO names (name) VALUES (:name)",
"write": true
}
}
}
}
}
.. [[[end]]]
This configuration will create a page at ``/mydatabase/add_name`` displaying a form with a ``name`` field. Submitting that form will execute the configured ``INSERT`` query.
@ -245,15 +398,14 @@ You can customize how Datasette represents success and errors using the followin
For example:
.. code-block:: json
{
.. [[[cog
metadata_example(cog, {
"databases": {
"mydatabase": {
"queries": {
"add_name": {
"sql": "INSERT INTO names (name) VALUES (:name)",
"write": true,
"write": True,
"on_success_message": "Name inserted",
"on_success_redirect": "/mydatabase/names",
"on_error_message": "Name insert failed",
@ -262,7 +414,46 @@ For example:
}
}
}
}
})
.. ]]]
.. tab:: YAML
.. code-block:: yaml
databases:
mydatabase:
queries:
add_name:
sql: INSERT INTO names (name) VALUES (:name)
write: true
on_success_message: Name inserted
on_success_redirect: /mydatabase/names
on_error_message: Name insert failed
on_error_redirect: /mydatabase
.. tab:: JSON
.. code-block:: json
{
"databases": {
"mydatabase": {
"queries": {
"add_name": {
"sql": "INSERT INTO names (name) VALUES (:name)",
"write": true,
"on_success_message": "Name inserted",
"on_success_redirect": "/mydatabase/names",
"on_error_message": "Name insert failed",
"on_error_redirect": "/mydatabase"
}
}
}
}
}
.. [[[end]]]
You can use ``"params"`` to explicitly list the named parameters that should be displayed as form fields - otherwise they will be automatically detected.
@ -300,10 +491,10 @@ Available magic parameters are:
``_random_chars_*`` - e.g. ``_random_chars_128``
A random string of characters of the specified length.
Here's an example configuration (this time using ``metadata.yaml`` since that provides better support for multi-line SQL queries) that adds a message from the authenticated user, storing various pieces of additional metadata using magic parameters:
.. code-block:: yaml
Here's an example configuration that adds a message from the authenticated user, storing various pieces of additional metadata using magic parameters:
.. [[[cog
metadata_example(cog, yaml="""
databases:
mydatabase:
queries:
@ -317,6 +508,47 @@ Here's an example configuration (this time using ``metadata.yaml`` since that pr
:_actor_id, :message, :_now_datetime_utc
)
write: true
""")
.. ]]]
.. tab:: YAML
.. code-block:: yaml
databases:
mydatabase:
queries:
add_message:
allow:
id: "*"
sql: |-
INSERT INTO messages (
user_id, message, datetime
) VALUES (
:_actor_id, :message, :_now_datetime_utc
)
write: true
.. tab:: JSON
.. code-block:: json
{
"databases": {
"mydatabase": {
"queries": {
"add_message": {
"allow": {
"id": "*"
},
"sql": "INSERT INTO messages (\n user_id, message, datetime\n) VALUES (\n :_actor_id, :message, :_now_datetime_utc\n)",
"write": true
}
}
}
}
}
.. [[[end]]]
The form presented at ``/mydatabase/add_message`` will have just a field for ``message`` - the other parameters will be populated by the magic parameter mechanism.

Wyświetl plik

@ -76,6 +76,7 @@ setup(
"blacken-docs",
"sphinx-copybutton",
"sphinx-inline-tabs",
"ruamel.yaml",
],
"test": [
"pytest>=5.2.2",