id,page,ref,title,content,breadcrumbs,references changelog:id10,changelog,id10,0.65 (2024-10-07),"Upgrade for compatibility with Python 3.13 (by vendoring Pint dependency). ( #2434 ) Dropped support for Python 3.8.","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/2434"", ""label"": ""#2434""}]" changelog:id100,changelog,id100,0.27.1 (2019-05-09),"Tiny bugfix release: don't install tests/ in the wrong place. Thanks, Veit Heller.","[""Changelog""]",[] changelog:id101,changelog,id101,0.27 (2019-01-31),"New command: datasette plugins ( documentation ) shows you the currently installed list of plugins. Datasette can now output newline-delimited JSON using the new ?_shape=array&_nl=on query string option. Added documentation on The Datasette Ecosystem . Now using Python 3.7.2 as the base for the official Datasette Docker image .","[""Changelog""]","[{""href"": ""http://ndjson.org/"", ""label"": ""newline-delimited JSON""}, {""href"": ""https://hub.docker.com/r/datasetteproject/datasette/"", ""label"": ""Datasette Docker image""}]" changelog:id102,changelog,id102,0.26.1 (2019-01-10),"/-/versions now includes SQLite compile_options ( #396 ) datasetteproject/datasette Docker image now uses SQLite 3.26.0 ( #397 ) Cleaned up some deprecation warnings under Python 3.7","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/396"", ""label"": ""#396""}, {""href"": ""https://hub.docker.com/r/datasetteproject/datasette"", ""label"": ""datasetteproject/datasette""}, {""href"": ""https://github.com/simonw/datasette/issues/397"", ""label"": ""#397""}]" changelog:id103,changelog,id103,0.26 (2019-01-02),"datasette serve --reload now restarts Datasette if a database file changes on disk. datasette publish now now takes an optional --alias mysite.now.sh argument. This will attempt to set an alias after the deploy completes. Fixed a bug where the advanced CSV export form failed to include the currently selected filters ( #393 )","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/393"", ""label"": ""#393""}]" changelog:id104,changelog,id104,0.25.2 (2018-12-16),"datasette publish heroku now uses the python-3.6.7 runtime Added documentation on how to build the documentation Added documentation covering our release process Upgraded to pytest 4.0.2","[""Changelog""]",[] changelog:id105,changelog,id105,0.25.1 (2018-11-04),"Documentation improvements plus a fix for publishing to Zeit Now. datasette publish now now uses Zeit's v1 platform, to work around the new 100MB image limit. Thanks, @slygent - closes #366 .","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/366"", ""label"": ""#366""}]" changelog:id106,changelog,id106,0.25 (2018-09-19),"New plugin hooks, improved database view support and an easier way to use more recent versions of SQLite. New publish_subcommand plugin hook. A plugin can now add additional datasette publish publishers in addition to the default now and heroku , both of which have been refactored into default plugins. publish_subcommand documentation . Closes #349 New render_cell plugin hook. Plugins can now customize how values are displayed in the HTML tables produced by Datasette's browsable interface. datasette-json-html and datasette-render-images are two new plugins that use this hook. render_cell documentation . Closes #352 New extra_body_script plugin hook, enabling plugins to provide additional JavaScript that should be added to the page footer. extra_body_script documentation . extra_css_urls and extra_js_urls hooks now take additional optional parameters, allowing them to be more selective about which pages they apply to. Documentation . You can now use the sortable_columns metadata setting to explicitly enable sort-by-column in the interface for database views, as well as for specific tables. The new fts_table and fts_pk metadata settings can now be used to explicitly configure full-text search for a table or a view , even if that table is not directly coupled to the SQLite FTS feature in the database schema itself. Datasette will now use pysqlite3 in place of the standard library sqlite3 module if it has been installed in the current environment. This makes it much easier to run Datasette against a more recent version of SQLite, including the just-released SQLite 3.25.0 which adds window function support. More details on how to use this in #360 New mechanism that allows plugin configuration options to be set using metadata.json .","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/349"", ""label"": ""#349""}, {""href"": ""https://github.com/simonw/datasette-json-html"", ""label"": ""datasette-json-html""}, {""href"": ""https://github.com/simonw/datasette-render-images"", ""label"": ""datasette-render-images""}, {""href"": ""https://github.com/simonw/datasette/issues/352"", ""label"": ""#352""}, {""href"": ""https://github.com/coleifer/pysqlite3"", ""label"": ""pysqlite3""}, {""href"": ""https://www.sqlite.org/releaselog/3_25_0.html"", ""label"": ""SQLite 3.25.0""}, {""href"": ""https://github.com/simonw/datasette/issues/360"", ""label"": ""#360""}]" changelog:id107,changelog,id107,0.24 (2018-07-23),"A number of small new features: datasette publish heroku now supports --extra-options , fixes #334 Custom error message if SpatiaLite is needed for specified database, closes #331 New config option: truncate_cells_html for truncating long cell values in HTML view - closes #330 Documentation for datasette publish and datasette package , closes #337 Fixed compatibility with Python 3.7 datasette publish heroku now supports app names via the -n option, which can also be used to overwrite an existing application [Russ Garrett] Title and description metadata can now be set for canned SQL queries , closes #342 New force_https_on config option, fixes https:// API URLs when deploying to Zeit Now - closes #333 ?_json_infinity=1 query string argument for handling Infinity/-Infinity values in JSON, closes #332 URLs displayed in the results of custom SQL queries are now URLified, closes #298","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/334"", ""label"": ""#334""}, {""href"": ""https://github.com/simonw/datasette/issues/331"", ""label"": ""#331""}, {""href"": ""https://github.com/simonw/datasette/issues/330"", ""label"": ""#330""}, {""href"": ""https://github.com/simonw/datasette/issues/337"", ""label"": ""#337""}, {""href"": ""https://github.com/simonw/datasette/issues/342"", ""label"": ""#342""}, {""href"": ""https://github.com/simonw/datasette/issues/333"", ""label"": ""#333""}, {""href"": ""https://github.com/simonw/datasette/issues/332"", ""label"": ""#332""}, {""href"": ""https://github.com/simonw/datasette/issues/298"", ""label"": ""#298""}]" changelog:id11,changelog,id11,0.64.8 (2024-06-21),"Security improvement: 404 pages used to reflect content from the URL path, which could be used to display misleading information to Datasette users. 404 errors no longer display additional information from the URL. ( #2359 ) Backported a better fix for correctly extracting named parameters from canned query SQL against SQLite 3.46.0. ( #2353 )","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/2359"", ""label"": ""#2359""}, {""href"": ""https://github.com/simonw/datasette/issues/2353"", ""label"": ""#2353""}]" changelog:id116,changelog,id116,0.23.2 (2018-07-07),"Minor bugfix and documentation release. CSV export now respects --cors , fixes #326 Installation instructions , including docker image - closes #328 Fix for row pages for tables with / in, closes #325","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/326"", ""label"": ""#326""}, {""href"": ""https://github.com/simonw/datasette/issues/328"", ""label"": ""#328""}, {""href"": ""https://github.com/simonw/datasette/issues/325"", ""label"": ""#325""}]" changelog:id12,changelog,id12,0.64.7 (2024-06-12),Fixed a bug where canned queries with named parameters threw an error when run against SQLite 3.46.0. ( #2353 ),"[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/2353"", ""label"": ""#2353""}]" changelog:id120,changelog,id120,0.23.1 (2018-06-21),"Minor bugfix release. Correctly display empty strings in HTML table, closes #314 Allow ""."" in database filenames, closes #302 404s ending in slash redirect to remove that slash, closes #309 Fixed incorrect display of compound primary keys with foreign key references. Closes #319 Docs + example of canned SQL query using || concatenation. Closes #321 Correctly display facets with value of 0 - closes #318 Default 'expand labels' to checked in CSV advanced export","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/314"", ""label"": ""#314""}, {""href"": ""https://github.com/simonw/datasette/issues/302"", ""label"": ""#302""}, {""href"": ""https://github.com/simonw/datasette/issues/309"", ""label"": ""#309""}, {""href"": ""https://github.com/simonw/datasette/issues/319"", ""label"": ""#319""}, {""href"": ""https://github.com/simonw/datasette/issues/321"", ""label"": ""#321""}, {""href"": ""https://github.com/simonw/datasette/issues/318"", ""label"": ""#318""}]" changelog:id127,changelog,id127,0.23 (2018-06-18),"This release features CSV export, improved options for foreign key expansions, new configuration settings and improved support for SpatiaLite. See datasette/compare/0.22.1...0.23 for a full list of commits added since the last release.","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/compare/0.22.1...0.23"", ""label"": ""datasette/compare/0.22.1...0.23""}]" changelog:id128,changelog,id128,0.22.1 (2018-05-23),"Bugfix release, plus we now use versioneer for our version numbers. Faceting no longer breaks pagination, fixes #282 Add __version_info__ derived from __version__ [Robert Gieseke] This might be tuple of more than two values (major and minor version) if commits have been made after a release. Add version number support with Versioneer. [Robert Gieseke] Versioneer Licence: Public Domain (CC0-1.0) Closes #273 Refactor inspect logic [Russ Garrett]","[""Changelog""]","[{""href"": ""https://github.com/warner/python-versioneer"", ""label"": ""versioneer""}, {""href"": ""https://github.com/simonw/datasette/issues/282"", ""label"": ""#282""}, {""href"": ""https://github.com/simonw/datasette/issues/273"", ""label"": ""#273""}]" changelog:id131,changelog,id131,0.22 (2018-05-20),"The big new feature in this release is Facets . Datasette can now apply faceted browse to any column in any table. It will also suggest possible facets. See the Datasette Facets announcement post for more details. In addition to the work on facets: Added docs for introspection endpoints New --config option, added --help-config , closes #274 Removed the --page_size= argument to datasette serve in favour of: datasette serve --config default_page_size:50 mydb.db Added new help section: datasette --help-config Config options: default_page_size Default page size for the table view (default=100) max_returned_rows Maximum rows that can be returned from a table or custom query (default=1000) sql_time_limit_ms Time limit for a SQL query in milliseconds (default=1000) default_facet_size Number of values to return for requested facets (default=30) facet_time_limit_ms Time limit for calculating a requested facet (default=200) facet_suggest_time_limit_ms Time limit for calculating a suggested facet (default=50) Only apply responsive table styles to .rows-and-column Otherwise they interfere with tables in the description, e.g. on https://fivethirtyeight.datasettes.com/fivethirtyeight/nba-elo%2Fnbaallelo Refactored views into new views/ modules, refs #256 Documentation for SQLite full-text search support, closes #253 /-/versions now includes SQLite fts_versions , closes #252","[""Changelog""]","[{""href"": ""https://simonwillison.net/2018/May/20/datasette-facets/"", ""label"": ""Datasette Facets""}, {""href"": ""https://docs.datasette.io/en/stable/introspection.html"", ""label"": ""docs for introspection endpoints""}, {""href"": ""https://github.com/simonw/datasette/issues/274"", ""label"": ""#274""}, {""href"": ""https://fivethirtyeight.datasettes.com/fivethirtyeight/nba-elo%2Fnbaallelo"", ""label"": ""https://fivethirtyeight.datasettes.com/fivethirtyeight/nba-elo%2Fnbaallelo""}, {""href"": ""https://github.com/simonw/datasette/issues/256"", ""label"": ""#256""}, {""href"": ""https://docs.datasette.io/en/stable/full_text_search.html"", ""label"": ""Documentation for SQLite full-text search""}, {""href"": ""https://github.com/simonw/datasette/issues/253"", ""label"": ""#253""}, {""href"": ""https://github.com/simonw/datasette/issues/252"", ""label"": ""#252""}]" changelog:id136,changelog,id136,0.21 (2018-05-05),"New JSON _shape= options, the ability to set table _size= and a mechanism for searching within specific columns. Default tests to using a longer timelimit Every now and then a test will fail in Travis CI on Python 3.5 because it hit the default 20ms SQL time limit. Test fixtures now default to a 200ms time limit, and we only use the 20ms time limit for the specific test that tests query interruption. This should make our tests on Python 3.5 in Travis much more stable. Support _search_COLUMN=text searches, closes #237 Show version on /-/plugins page, closes #248 ?_size=max option, closes #249 Added /-/versions and /-/versions.json , closes #244 Sample output: { ""python"": { ""version"": ""3.6.3"", ""full"": ""3.6.3 (default, Oct 4 2017, 06:09:38) \n[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.37)]"" }, ""datasette"": { ""version"": ""0.20"" }, ""sqlite"": { ""version"": ""3.23.1"", ""extensions"": { ""json1"": null, ""spatialite"": ""4.3.0a"" } } } Renamed ?_sql_time_limit_ms= to ?_timelimit , closes #242 New ?_shape=array option + tweaks to _shape , closes #245 Default is now ?_shape=arrays (renamed from lists ) New ?_shape=array returns an array of objects as the root object Changed ?_shape=object to return the object as the root Updated docs FTS tables now detected by inspect() , closes #240 New ?_size=XXX query string parameter for table view, closes #229 Also added documentation for all of the _special arguments. Plus deleted some duplicate logic implementing _group_count . If max_returned_rows==page_size , increment max_returned_rows - fixes #230 New hidden: True option for table metadata, closes #239 Hide idx_* tables if spatialite detected, closes #228 Added class=rows-and-columns to custom query results table Added CSS class rows-and-columns to main table label_column option in metadata.json - closes #234","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/237"", ""label"": ""#237""}, {""href"": ""https://github.com/simonw/datasette/issues/248"", ""label"": ""#248""}, {""href"": ""https://github.com/simonw/datasette/issues/249"", ""label"": ""#249""}, {""href"": ""https://github.com/simonw/datasette/issues/244"", ""label"": ""#244""}, {""href"": ""https://github.com/simonw/datasette/issues/242"", ""label"": ""#242""}, {""href"": ""https://github.com/simonw/datasette/issues/245"", ""label"": ""#245""}, {""href"": ""https://github.com/simonw/datasette/issues/240"", ""label"": ""#240""}, {""href"": ""https://github.com/simonw/datasette/issues/229"", ""label"": ""#229""}, {""href"": ""https://github.com/simonw/datasette/issues/230"", ""label"": ""#230""}, {""href"": ""https://github.com/simonw/datasette/issues/239"", ""label"": ""#239""}, {""href"": ""https://github.com/simonw/datasette/issues/228"", ""label"": ""#228""}, {""href"": ""https://github.com/simonw/datasette/issues/234"", ""label"": ""#234""}]" changelog:id14,changelog,id14,0.64.6 (2023-12-22),Fixed a bug where CSV export with expanded labels could fail if a foreign key reference did not correctly resolve. ( #2214 ),"[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/2214"", ""label"": ""#2214""}]" changelog:id149,changelog,id149,0.20 (2018-04-20),"Mostly new work on the Plugins mechanism: plugins can now bundle static assets and custom templates, and datasette publish has a new --install=name-of-plugin option. Add col-X classes to HTML table on custom query page Fixed out-dated template in documentation Plugins can now bundle custom templates, #224 Added /-/metadata /-/plugins /-/inspect, #225 Documentation for --install option, refs #223 Datasette publish/package --install option, #223 Fix for plugins in Python 3.5, #222 New plugin hooks: extra_css_urls() and extra_js_urls(), #214 /-/static-plugins/PLUGIN_NAME/ now serves static/ from plugins now gets class=""col-X"" - plus added col-X documentation Use to_css_class for table cell column classes This ensures that columns with spaces in the name will still generate usable CSS class names. Refs #209 Add column name classes to s, make PK bold [Russ Garrett] Don't duplicate simple primary keys in the link column [Russ Garrett] When there's a simple (single-column) primary key, it looks weird to duplicate it in the link column. This change removes the second PK column and treats the link column as if it were the PK column from a header/sorting perspective. Correct escaping for HTML display of row links [Russ Garrett] Longer time limit for test_paginate_compound_keys It was failing intermittently in Travis - see #209 Use application/octet-stream for downloadable databases Updated PyPI classifiers Updated PyPI link to pypi.org","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/224"", ""label"": ""#224""}, {""href"": ""https://github.com/simonw/datasette/issues/225"", ""label"": ""#225""}, {""href"": ""https://github.com/simonw/datasette/issues/223"", ""label"": ""#223""}, {""href"": ""https://github.com/simonw/datasette/issues/223"", ""label"": ""#223""}, {""href"": ""https://github.com/simonw/datasette/issues/222"", ""label"": ""#222""}, {""href"": ""https://github.com/simonw/datasette/issues/214"", ""label"": ""#214""}, {""href"": ""https://github.com/simonw/datasette/issues/209"", ""label"": ""#209""}, {""href"": ""https://github.com/simonw/datasette/issues/209"", ""label"": ""#209""}]" changelog:id15,changelog,id15,0.64.5 (2023-10-08),"Dropped dependency on click-default-group-wheel , which could cause a dependency conflict. ( #2197 )","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/2197"", ""label"": ""#2197""}]" changelog:id158,changelog,id158,0.19 (2018-04-16),"This is the first preview of the new Datasette plugins mechanism. Only two plugin hooks are available so far - for custom SQL functions and custom template filters. There's plenty more to come - read the documentation and get involved in the tracking ticket if you have feedback on the direction so far. Fix for _sort_desc=sortable_with_nulls test, refs #216 Fixed #216 - paginate correctly when sorting by nullable column Initial documentation for plugins, closes #213 https://docs.datasette.io/en/stable/plugins.html New --plugins-dir=plugins/ option ( #212 ) New option causing Datasette to load and evaluate all of the Python files in the specified directory and register any plugins that are defined in those files. This new option is available for the following commands: datasette serve mydb.db --plugins-dir=plugins/ datasette publish now/heroku mydb.db --plugins-dir=plugins/ datasette package mydb.db --plugins-dir=plugins/ Start of the plugin system, based on pluggy ( #210 ) Uses https://pluggy.readthedocs.io/ originally created for the py.test project We're starting with two plugin hooks: prepare_connection(conn) This is called when a new SQLite connection is created. It can be used to register custom SQL functions. prepare_jinja2_environment(env) This is called with the Jinja2 environment. It can be used to register custom template tags and filters. An example plugin which uses these two hooks can be found at https://github.com/simonw/datasette-plugin-demos or installed using pip install datasette-plugin-demos Refs #14 Return HTTP 405 on InvalidUsage rather than 500. [Russ Garrett] This also stops it filling up the logs. This happens for HEAD requests at the moment - which perhaps should be handled better, but that's a different issue.","[""Changelog""]","[{""href"": ""https://docs.datasette.io/en/stable/plugins.html"", ""label"": ""the documentation""}, {""href"": ""https://github.com/simonw/datasette/issues/14"", ""label"": ""the tracking ticket""}, {""href"": ""https://github.com/simonw/datasette/issues/216"", ""label"": ""#216""}, {""href"": ""https://github.com/simonw/datasette/issues/216"", ""label"": ""#216""}, {""href"": ""https://github.com/simonw/datasette/issues/213"", ""label"": ""#213""}, {""href"": ""https://docs.datasette.io/en/stable/plugins.html"", ""label"": ""https://docs.datasette.io/en/stable/plugins.html""}, {""href"": ""https://github.com/simonw/datasette/issues/212"", ""label"": ""#212""}, {""href"": ""https://github.com/simonw/datasette/issues/14"", ""label"": ""#210""}, {""href"": ""https://pluggy.readthedocs.io/"", ""label"": ""https://pluggy.readthedocs.io/""}, {""href"": ""https://github.com/simonw/datasette-plugin-demos"", ""label"": ""https://github.com/simonw/datasette-plugin-demos""}, {""href"": ""https://github.com/simonw/datasette/issues/14"", ""label"": ""#14""}]" changelog:id16,changelog,id16,0.64.4 (2023-09-21),Fix for a crashing bug caused by viewing the table page for a named in-memory database. ( #2189 ),"[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/2189"", ""label"": ""#2189""}]" changelog:id165,changelog,id165,0.18 (2018-04-14),"This release introduces support for units , contributed by Russ Garrett ( #203 ). You can now optionally specify the units for specific columns using metadata.json . Once specified, units will be displayed in the HTML view of your table. They also become available for use in filters - if a column is configured with a unit of distance, you can request all rows where that column is less than 50 meters or more than 20 feet for example. Link foreign keys which don't have labels. [Russ Garrett] This renders unlabeled FKs as simple links. Also includes bonus fixes for two minor issues: In foreign key link hrefs the primary key was escaped using HTML escaping rather than URL escaping. This broke some non-integer PKs. Print tracebacks to console when handling 500 errors. Fix SQLite error when loading rows with no incoming FKs. [Russ Garrett] This fixes an error caused by an invalid query when loading incoming FKs. The error was ignored due to async but it still got printed to the console. Allow custom units to be registered with Pint. [Russ Garrett] Support units in filters. [Russ Garrett] Tidy up units support. [Russ Garrett] Add units to exported JSON Units key in metadata skeleton Docs Initial units support. [Russ Garrett] Add support for specifying units for a column in metadata.json and rendering them on display using pint","[""Changelog""]","[{""href"": ""https://docs.datasette.io/en/stable/metadata.html#specifying-units-for-a-column"", ""label"": ""support for units""}, {""href"": ""https://github.com/simonw/datasette/issues/203"", ""label"": ""#203""}, {""href"": ""https://pint.readthedocs.io/en/latest/"", ""label"": ""pint""}]" changelog:id167,changelog,id167,0.17 (2018-04-13),Release 0.17 to fix issues with PyPI,"[""Changelog""]",[] changelog:id168,changelog,id168,0.16 (2018-04-13),"Better mechanism for handling errors; 404s for missing table/database New error mechanism closes #193 404s for missing tables/databases closes #184 long_description in markdown for the new PyPI Hide SpatiaLite system tables. [Russ Garrett] Allow explain select / explain query plan select #201 Datasette inspect now finds primary_keys #195 Ability to sort using form fields (for mobile portrait mode) #199 We now display sort options as a select box plus a descending checkbox, which means you can apply sort orders even in portrait mode on a mobile phone where the column headers are hidden.","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/193"", ""label"": ""#193""}, {""href"": ""https://github.com/simonw/datasette/issues/184"", ""label"": ""#184""}, {""href"": ""https://github.com/simonw/datasette/issues/201"", ""label"": ""#201""}, {""href"": ""https://github.com/simonw/datasette/issues/195"", ""label"": ""#195""}, {""href"": ""https://github.com/simonw/datasette/issues/199"", ""label"": ""#199""}]" changelog:id17,changelog,id17,0.64.2 (2023-03-08),"Fixed a bug with datasette publish cloudrun where deploys all used the same Docker image tag. This was mostly inconsequential as the service is deployed as soon as the image has been pushed to the registry, but could result in the incorrect image being deployed if two different deploys for two separate services ran at exactly the same time. ( #2036 )","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/2036"", ""label"": ""#2036""}]" changelog:id174,changelog,id174,0.15 (2018-04-09),"The biggest new feature in this release is the ability to sort by column. On the table page the column headers can now be clicked to apply sort (or descending sort), or you can specify ?_sort=column or ?_sort_desc=column directly in the URL. table_rows => table_rows_count , filtered_table_rows => filtered_table_rows_count Renamed properties. Closes #194 New sortable_columns option in metadata.json to control sort options. You can now explicitly set which columns in a table can be used for sorting using the _sort and _sort_desc arguments using metadata.json : { ""databases"": { ""database1"": { ""tables"": { ""example_table"": { ""sortable_columns"": [ ""height"", ""weight"" ] } } } } } Refs #189 Column headers now link to sort/desc sort - refs #189 _sort and _sort_desc parameters for table views Allows for paginated sorted results based on a specified column. Refs #189 Total row count now correct even if _next applied Use .custom_sql() for _group_count implementation (refs #150 ) Make HTML title more readable in query template ( #180 ) [Ryan Pitts] New ?_shape=objects/object/lists param for JSON API ( #192 ) New _shape= parameter replacing old .jsono extension Now instead of this: /database/table.jsono We use the _shape parameter like this: /database/table.json?_shape=objects Also introduced a new _shape called object which looks like this: /database/table.json?_shape=object Returning an object for the rows key: ... ""rows"": { ""pk1"": { ... }, ""pk2"": { ... } } Refs #122 Utility for writing test database fixtures to a .db file python tests/fixtures.py /tmp/hello.db This is useful for making a SQLite database of the test fixtures for interactive exploration. Compound primary key _next= now plays well with extra filters Closes #190 Fixed bug with keyset pagination over compound primary keys Refs #190 Database/Table views inherit source/license/source_url/license_url metadata If you set the source_url/license_url/source/license fields in your root metadata those values will now be inherited all the way down to the database and table templates. The title/description are NOT inherited. Also added unit tests for the HTML generated by the metadata. Refs #185 Add metadata, if it exists, to heroku temp dir ( #178 ) [Tony Hirst] Initial documentation for pagination Broke up test_app into test_api and test_html Fixed bug with .json path regular expression I had a table called geojson and it caused an exception because the regex was matching .json and not \.json Deploy to Heroku with Python 3.6.3","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/194"", ""label"": ""#194""}, {""href"": ""https://github.com/simonw/datasette/issues/189"", ""label"": ""#189""}, {""href"": ""https://github.com/simonw/datasette/issues/189"", ""label"": ""#189""}, {""href"": ""https://github.com/simonw/datasette/issues/189"", ""label"": ""#189""}, {""href"": ""https://github.com/simonw/datasette/issues/150"", ""label"": ""#150""}, {""href"": ""https://github.com/simonw/datasette/issues/180"", ""label"": ""#180""}, {""href"": ""https://github.com/simonw/datasette/issues/192"", ""label"": ""#192""}, {""href"": ""https://github.com/simonw/datasette/issues/122"", ""label"": ""#122""}, {""href"": ""https://github.com/simonw/datasette/issues/190"", ""label"": ""#190""}, {""href"": ""https://github.com/simonw/datasette/issues/190"", ""label"": ""#190""}, {""href"": ""https://github.com/simonw/datasette/issues/185"", ""label"": ""#185""}, {""href"": ""https://github.com/simonw/datasette/issues/178"", ""label"": ""#178""}]" changelog:id18,changelog,id18,0.64.1 (2023-01-11),"Documentation now links to a current source of information for installing Python 3. ( #1987 ) Incorrectly calling the Datasette constructor using Datasette(""path/to/data.db"") instead of Datasette([""path/to/data.db""]) now returns a useful error message. ( #1985 )","[""Changelog""]","[{""href"": ""https://github.com/simonw/datasette/issues/1987"", ""label"": ""#1987""}, {""href"": ""https://github.com/simonw/datasette/issues/1985"", ""label"": ""#1985""}]" changelog:id187,changelog,id187,0.14 (2017-12-09),"The theme of this release is customization: Datasette now allows every aspect of its presentation to be customized either using additional CSS or by providing entirely new templates. Datasette's metadata.json format has also been expanded, to allow per-database and per-table metadata. A new datasette skeleton command can be used to generate a skeleton JSON file ready to be filled in with per-database and per-table details. The metadata.json file can also be used to define canned queries , as a more powerful alternative to SQL views. extra_css_urls / extra_js_urls in metadata A mechanism in the metadata.json format for adding custom CSS and JS urls. Create a metadata.json file that looks like this: { ""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"" ] } Then start datasette like this: datasette mydb.db --metadata=metadata.json The CSS and JavaScript files will be linked in the of every page. You can also specify a SRI (subresource integrity hash) for these assets: { ""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="" } ] } Modern browsers will only execute the stylesheet or JavaScript if the SRI hash matches the content served. You can generate hashes using https://www.srihash.org/ Auto-link column values that look like URLs ( #153 ) CSS styling hooks as classes on the body ( #153 ) Every template now gets CSS classes in the body designed to support custom styling. The index template (the top level page at / ) gets this: The database template ( /dbname/ ) gets this: The table template ( /dbname/tablename ) gets: The row template ( /dbname/tablename/rowid ) gets: The db-x and table-x classes use the database or table names themselves IF they are valid CSS identifiers. If they aren't, we strip any invalid characters out and append a 6 character md5 digest of the original name, in order to ensure that multiple tables which resolve to the same stripped character version still have different CSS classes. Some examples (extracted from the unit tests): ""simple"" => ""simple"" ""MixedCase"" => ""MixedCase"" ""-no-leading-hyphens"" => ""no-leading-hyphens-65bea6"" ""_no-leading-underscores"" => ""no-leading-underscores-b921bc"" ""no spaces"" => ""no-spaces-7088d7"" ""-"" => ""336d5e"" ""no $ characters"" => ""no--characters-59e024"" datasette --template-dir=mytemplates/ argument You can now pass an additional argument specifying a directory to look for custom templates in. Datasette will fall back on the default templates if a template is not found in that directory. Ability to over-ride templates for individual tables/databases. It is now possible to over-ride templates on a per-database / per-row or per- table basis. When you access e.g. /mydatabase/mytable Datasette will look for the following: - table-mydatabase-mytable.html - table.html If you provided a --template-dir argument to datasette serve it will look in that directory first. The lookup rules are as follows: Index page (/): index.html Database page (/mydatabase): database-mydatabase.html database.html Table page (/mydatabase/mytable): table-mydatabase-mytable.html table.html Row page (/mydatabase/mytable/id): row-mydatabase-mytable.html row.html If a table name has spaces or other unexpected characters in it, the template filename will follow the same rules as our custom CSS classes - for example, a table called ""Food Trucks"" will attempt to load the following templates: table-mydatabase-Food-Trucks-399138.html table.html It is possible to extend the default templates using Jinja template inheritance. If you want to customize EVERY row template with some additional content you can do so by creating a row.html template like this: {% extends ""default:row.html"" %} {% block content %}

EXTRA HTML AT THE TOP OF THE CONTENT BLOCK

This line renders the original block:

{{ super() }} {% endblock %} --static option for datasette serve ( #160 ) You can now tell Datasette to serve static files from a specific location at a specific mountpoint. For example: datasette serve mydb.db --static extra-css:/tmp/static/css Now if you visit this URL: http://localhost:8001/extra-css/blah.css The following file will be served: /tmp/static/css/blah.css Canned query support. Named canned queries can now be defined in metadata.json like this: { ""databases"": { ""timezones"": { ""queries"": { ""timezone_for_point"": ""select tzid from timezones ..."" } } } } These will be shown in a new ""Queries"" section beneath ""Views"" on the database page. New datasette skeleton command for generating metadata.json ( #164 ) metadata.json support for per-table/per-database metadata ( #165 ) Also added support for descriptions and HTML descriptions. Here's an example metadata.json file illustrating custom per-database and per- table metadata: { ""title"": ""Overall datasette title"", ""description_html"": ""This is a description with HTML."", ""databases"": { ""db1"": { ""title"": ""First database"", ""description"": ""This is a string description & has no HTML"", ""license_url"": ""http://example.com/"", ""license"": ""The example license"", ""queries"": { ""canned_query"": ""select * from table1 limit 3;"" }, ""tables"": { ""table1"": { ""title"": ""Custom title for table1"", ""description"": ""Tables can have descriptions too"", ""source"": ""This has a custom source"", ""source_url"": ""http://example.com/"" } } } } } Renamed datasette build command to datasette inspect ( #130 ) Upgrade to Sanic 0.7.0 ( #168 ) https://github.com/channelcat/sanic/releases/tag/0.7.0 Package and publish commands now accept --static and --template-dir Example usage: datasette package --static css:extra-css/ --static js:extra-js/ \ sf-trees.db --template-dir templates/ --tag sf-trees --branch master This creates a local Docker image that includes copies of the templates/, extra-css/ and extra-js/ directories. You can then run it like this: docker run -p 8001:8001 sf-trees For publishing to Zeit now: datasette publish now --static css:extra-css/ --static js:extra-js/ \ sf-trees.db --template-dir templates/ --name sf-trees --branch master HTML comment showing which templates were considered for a page ( #171 )","[""Changelog""]","[{""href"": ""https://docs.datasette.io/en/stable/custom_templates.html"", ""label"": ""to be customized""}, {""href"": ""https://docs.datasette.io/en/stable/metadata.html"", ""label"": ""metadata.json format""}, {""href"": ""https://docs.datasette.io/en/stable/sql_queries.html#canned-queries"", ""label"": ""canned queries""}, {""href"": ""https://www.srihash.org/"", ""label"": ""https://www.srihash.org/""}, {""href"": ""https://github.com/simonw/datasette/issues/153"", ""label"": ""#153""}, {""href"": ""https://github.com/simonw/datasette/issues/153"", ""label"": ""#153""}, {""href"": ""https://github.com/simonw/datasette/issues/160"", ""label"": ""#160""}, {""href"": ""https://github.com/simonw/datasette/issues/164"", ""label"": ""#164""}, {""href"": ""https://github.com/simonw/datasette/issues/165"", ""label"": ""#165""}, {""href"": ""https://github.com/simonw/datasette/issues/130"", ""label"": ""#130""}, {""href"": ""https://github.com/simonw/datasette/issues/168"", ""label"": ""#168""}, {""href"": ""https://github.com/channelcat/sanic/releases/tag/0.7.0"", ""label"": ""https://github.com/channelcat/sanic/releases/tag/0.7.0""}, {""href"": ""https://github.com/simonw/datasette/issues/171"", ""label"": ""#171""}]" changelog:id19,changelog,id19,0.64 (2023-01-09),"Datasette now strongly recommends against allowing arbitrary SQL queries if you are using SpatiaLite . SpatiaLite includes SQL functions that could cause the Datasette server to crash. See SpatiaLite for more details. New default_allow_sql setting, providing an easier way to disable all arbitrary SQL execution by end users: datasette --setting default_allow_sql off . See also Controlling the ability to execute arbitrary SQL . ( #1409 ) Building a location to time zone API with SpatiaLite is a new Datasette tutorial showing how to safely use SpatiaLite to create a location to time zone API. New documentation about how to debug problems loading SQLite extensions . The error message shown when an extension cannot be loaded has also been improved. ( #1979 ) Fixed an accessibility issue: the