kopia lustrzana https://github.com/simonw/datasette
Applied sphinx-inline-tabs to remaining examples, refs #1153
rodzic
0183e1a72d
commit
c076fb65e0
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
124
docs/facets.rst
124
docs/facets.rst
|
@ -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
|
||||
----------------
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
153
docs/plugins.rst
153
docs/plugins.rst
|
@ -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]]]
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
1
setup.py
1
setup.py
|
@ -76,6 +76,7 @@ setup(
|
|||
"blacken-docs",
|
||||
"sphinx-copybutton",
|
||||
"sphinx-inline-tabs",
|
||||
"ruamel.yaml",
|
||||
],
|
||||
"test": [
|
||||
"pytest>=5.2.2",
|
||||
|
|
Ładowanie…
Reference in New Issue