Datasette 0.65.5 配置参数详解

Datasette 0.65.5 配置体系逐项实测:settings.json 20 项运行时参数、metadata.json 元数据与 allow 权限块、--setting 覆盖优先级、配置目录模式与 datasette.yaml 版本边界排障实录,附生产配置模板。

DatasetteDatasetteSQLite2026/10/25

Datasette 0.65.5 配置参数详解

目标:把 Datasette 0.65.5 的配置体系讲透——settings.json 运行时参数、metadata.json 元数据与权限、--setting 命令行覆盖、配置目录模式,逐项给出实测命令与回显,并澄清 0.65.x 稳定版与 1.0 alpha 配置文件的差异。已在 Ubuntu 22.04(Python 3.10.12、Datasette 0.65.5)实测通过。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • Python:3.10.12;Datasette:0.65.5(venv 位于 /opt/datasette/venv)
  • 部署形态:systemd 托管,配置目录 /srv/datasette/app/,监听 127.0.0.1:8001
  • 演示数据:sales.db(orders 5000 行、customers 300 行)、inventory.db(products 5 行),由 Python 脚本生成
  • 配置文件实测对象:/srv/datasette/app/settings.json、/srv/datasette/app/metadata.json

二、前置条件

  • 已按《Ubuntu 22.04 安装 Datasette 0.65.5 指南》装好并跑通 systemd 托管实例;
  • 本文所有 curl 验证命令在服务器本机执行即可独立复现;涉及改配置的步骤都给出「修改 → 重启 → 验证」闭环。

三、参数的三个载体与优先级

Datasette 0.65.5 的配置分散在三个载体,作用域各不相同:

载体位置管什么改动生效方式
settings.json配置目录内运行时参数(分页、超时、下载、缓存等 20 项)实测需重启进程
metadata.json配置目录内(或用 -m 指定路径)实例/库/表的标题、来源、许可证、默认排序、预定义查询、访问控制配置目录模式下实测需重启进程
--setting 名称 值启动命令行临时覆盖任意运行时参数仅当次启动有效

优先级实测:命令行 --setting 高于 settings.json。在配置目录已有 settings.json(default_page_size=20)的情况下,启动时加 --setting default_page_size 3:

/opt/datasette/venv/bin/datasette . --setting default_page_size 3 --port 8013 --get /sales/customers.json

返回体行数为 3(--setting 胜出):

settings.json=20 + --setting=3 → rows: 3

⚠️ 排障实录(生效方式):最初按「改文件即热生效」的预期修改 metadata.json 的 description 并立即查询 /-/metadata.json,等待 2 秒、6 秒返回的仍是旧值;systemctl restart datasette 后新值才出现。实测结论:0.65.5 配置目录模式下,settings.json 与 metadata.json 的改动都需要重启进程生效,不要依赖热加载。

四、运行时参数总览

datasette --help-settings 列出全部运行时参数(实测输出,默认值逐行照抄):

Settings:
  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)
  num_sql_threads              Number of threads in the thread pool for
                               executing SQLite queries (default=3)
  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)
  allow_facet                  Allow users to specify columns to facet using
                               ?_facet= parameter (default=True)
  default_allow_sql            Allow anyone to run arbitrary SQL queries
                               (default=True)
  allow_download               Allow users to download the original SQLite
                               database files (default=True)
  suggest_facets               Calculate and display suggested facets
                               (default=True)
  default_cache_ttl            Default HTTP cache TTL (used in Cache-Control:
                               max-age= header) (default=5)
  cache_size_kb                SQLite cache size in KB (0 == use SQLite
                               default) (default=0)
  allow_csv_stream             Allow .csv?_stream=1 to download all rows
                               (ignoring max_returned_rows) (default=True)
  max_csv_mb                   Maximum size allowed for CSV export in MB - set
                               0 to disable this limit (default=100)
  truncate_cells_html          Truncate cells longer than this in HTML table
                               view - set 0 to disable (default=2048)
  force_https_urls             Force URLs in API output to always use https://
                               protocol (default=False)
  template_debug               Allow display of template debug information
                               with ?_context=1 (default=False)
  trace_debug                  Allow display of SQL trace debug information
                               with ?_trace=1 (default=False)
  base_url                     Datasette URLs should use this base path
                               (default=/)

共 20 项。下面按用途分类逐项详解,每类都给出实测验证。

五、核心参数分类详解

5.1 分页与返回行数:default_page_size / max_returned_rows

  • default_page_size(默认 100):表视图与 .json 默认每页行数。
  • max_returned_rows(默认 1000):单表或自定义查询最多返回的行数,URL 参数 _size 的上限也由它约束。

实测环境:settings.json 设为 default_page_size: 20、max_returned_rows: 200,重启后查询:

curl -s http://127.0.0.1:8001/sales/orders.json | python3 -c "import json,sys;print('orders rows:',len(json.load(sys.stdin)['rows']))"
curl -s http://127.0.0.1:8001/sales/customers.json | python3 -c "import json,sys;print('customers rows:',len(json.load(sys.stdin)['rows']))"
orders rows: 20
customers rows: 20

再验证 max_returned_rows=200 对 _size 的钳制:

curl -s "http://127.0.0.1:8001/sales/orders.json?_size=500"
{"ok": false, "error": "_size must be <= 200", "status": 400, "title": null}

解读:default_page_size 管「默认显示多少」,max_returned_rows 管「最多能给多少」,超限直接 400 报错而不是静默截断。

5.2 SQL 执行护栏:sql_time_limit_ms / num_sql_threads / default_allow_sql

  • sql_time_limit_ms(默认 1000 毫秒):单条 SQL 的硬超时,超时即中断。
  • num_sql_threads(默认 3):执行 SQL 的线程池大小,决定并发查询能力。
  • default_allow_sql(默认 true):是否允许任意访问者在查询框执行只读 SQL;面向公众发布敏感数据时建议关。

实测 sql_time_limit_ms: 500(settings.json 设定值),故意提交一条 2 亿行的递归查询:

curl -s -G http://127.0.0.1:8001/sales.json --data-urlencode "sql=with recursive cnt(x) as (select 1 union all select x+1 from cnt limit 200000000) select count(*) from cnt"

返回(节选):

{"ok": false, "error": "<p>SQL query took too long. The time limit is controlled by the\n<a href=\"https://docs.datasette.io/en/stable/settings.html#sql-time-limit-ms\">sql_time_limit_ms</a>\nconfiguration option.</p>...", "status": 400, "title": "SQL Interrupted"}

解读:查询被准时中断,返回 400 与明确的错误页提示,慢查询不会拖垮实例——这正是 Datasette 敢把 SQL 查询框开放给公众的底气。

5.3 下载与导出:allow_download / allow_csv_stream / max_csv_mb

  • allow_download(默认 true):是否允许下载原始 .db 文件。
  • allow_csv_stream(默认 true):是否允许 .csv?_stream=1 全量流式导出(忽略 max_returned_rows)。
  • max_csv_mb(默认 100):CSV 导出大小上限(MB),0 表示不限制。

实测 allow_download: true 下原始库文件可直接下载:

curl -s -o /dev/null -w "GET /sales.db http_code=%{http_code} size=%{size_download}\n" http://127.0.0.1:8001/sales.db
GET /sales.db http_code=200 size=278528

下载到的字节数与磁盘上的 sales.db(278528 字节)一致。若实例只应对外提供查询页而不暴露原始文件,把 allow_download 设为 false 并重启即可(配置目录模式实测重启后生效)。

5.4 分面统计:allow_facet / suggest_facets / default_facet_size / facet_time_limit_ms / facet_suggest_time_limit_ms

  • allow_facet(默认 true):允许 URL 用 ?_facet=列名 请求分面。
  • suggest_facets(默认 true):在表页自动给出「建议分面」。
  • default_facet_size(默认 30):每个分面最多返回多少个取值。
  • facet_time_limit_ms(默认 200)/ facet_suggest_time_limit_ms(默认 50):分面计算与建议分面各自的超时。

💡 技术拓展:分面(facet)是 Datasette 数据探索的核心交互,类似电商网站的「按品牌/价格区间筛选」。业界常见的统计交互形态对比——

形态特点代表
分面统计 facet对列值分组计数,点击即筛选Datasette、Elasticsearch
透视表 pivot行列双维度聚合Metabase、Excel
预聚合 cube预先算好所有维度组合Apache Kylin、Cube.js

Datasette 采用即时计算的 facet:无需预聚合,代价是大表上受 facet_time_limit_ms 约束,超时的分面会被跳过而不是拖住页面。

5.5 缓存与性能:default_cache_ttl / cache_size_kb

  • default_cache_ttl(默认 5 秒):响应头 Cache-Control: max-age= 的值,面向公众的只读数据站可调大(如 3600)大幅降低后端压力。
  • cache_size_kb(默认 0):SQLite 自身页缓存大小,0 表示用 SQLite 默认值。

实测 settings.json 设为 default_cache_ttl: 30 的实例,响应头随之变化:

curl -s -I http://127.0.0.1:8001/sales/orders.json?_size=1 | grep -i "cache-control"
Cache-Control: max-age=30

当前实例全部 settings 的生效值可用内置端点一次看清(含来源合并后的结果):

curl -s http://127.0.0.1:8001/-/settings.json
{"default_page_size": 20, "max_returned_rows": 200, "num_sql_threads": 3, "sql_time_limit_ms": 500, "default_facet_size": 30, "facet_time_limit_ms": 200, "facet_suggest_time_limit_ms": 50, "allow_facet": true, "default_allow_sql": true, "allow_download": true, "suggest_facets": true, "default_cache_ttl": 30, "cache_size_kb": 0, "allow_csv_stream": true, "max_csv_mb": 100, "truncate_cells_html": 2048, "force_https_urls": false, "template_debug": false, "trace_debug": false, "base_url": "/"}

解读:未配置的项保持默认值(如 num_sql_threads: 3、base_url: "/"),配置过的项显示文件中的值——排障时先查这个端点,比翻配置文件更可靠。

5.6 单元格与调试:truncate_cells_html / template_debug / trace_debug

  • truncate_cells_html(默认 2048):HTML 表格里超长单元格的截断长度,0 表示不截断。
  • template_debug(默认 false):开启后 URL 加 ?_context=1 可查看模板上下文。
  • trace_debug(默认 false):开启后 URL 加 ?_trace=1 可查看 SQL 执行轨迹。

两个调试项都会暴露内部结构,生产保持默认 false,只在排障时通过 --setting template_debug true 临时开启。

5.7 URL 与部署:base_url / force_https_urls

  • base_url(默认 /):把 Datasette 挂在子路径下(如 /data/)时设置,所有内部链接自动加前缀。
  • force_https_urls(默认 false):JSON 输出中的 URL 强制使用 https://,配合反向代理终止 TLS 时开启。

六、metadata.json 详解

metadata.json 是 Datasette 的「数据门户配置」:给实例、库、表挂标题、来源、许可证与预定义查询。本篇实测用的完整文件(/srv/datasette/app/metadata.json):

{
  "title": "销售数据探索平台",
  "description": "Datasette 0.65.5 实测示例:订单与库存数据目录",
  "license": "CC BY 4.0",
  "license_url": "https://creativecommons.org/licenses/by/4.0/",
  "source": "内部销售系统导出",
  "source_url": "https://data.example.com/sales",
  "databases": {
    "sales": {
      "description": "订单与客户维度数据",
      "tables": {
        "orders": {
          "description": "订单明细表,共 5000 行",
          "sort_desc": "created_at",
          "size": 20,
          "columns": {
            "amount": "订单金额(元)",
            "status": "订单状态"
          }
        },
        "customers": {
          "description": "客户维度表,共 300 行"
        }
      },
      "queries": {
        "region_summary": {
          "sql": "select region, count(*) as order_count, round(sum(amount), 2) as total_amount from orders group by region order by total_amount desc",
          "title": "按大区汇总",
          "description": "各区域订单数与销售总额"
        }
      }
    },
    "inventory": {
      "description": "商品库存数据"
    }
  }
}

逐级说明与实测:

  1. 实例级:title/description/license/license_url/source/source_url 显示在首页与每个页面页脚。验证:
curl -s http://127.0.0.1:8001/-/metadata.json | python3 -c "import json,sys;d=json.load(sys.stdin);print(d['title'],'|',d['license'])"
销售数据探索平台 | CC BY 4.0
  1. 库级 databases.<库名>.description:显示在库首页。
  2. 表级:description(表说明)、sort_desc(默认排序列,orders 表实测首页即按 created_at 倒序)、size(覆盖该表的分页大小,优先级高于 default_page_size)、columns(列说明,悬停显示)。
  3. 预定义查询 queries.<查询名>:把固定 SQL 发布成带标题的页面,业务方直接访问 /<库>/<查询名> 即可。实测:
curl -s "http://127.0.0.1:8001/sales/region_summary.json?_shape=array"
[{"region": "华东", "order_count": 1323, "total_amount": 6076873.85}, {"region": "西南", "order_count": 1196, "total_amount": 5483035.16}, {"region": "华南", "order_count": 1263, "total_amount": 5480607.81}, {"region": "华北", "order_count": 1218, "total_amount": 5463582.71}]

四个大区的订单数与总额一次返回,与非技术同事分享这个 URL 即可,无需让对方写 SQL。

七、访问控制:allow 权限块与 root 登录

metadata.json 的 allow 块按「实例 → 库 → 表」逐级收紧权限。实测用的私有配置(metadata-private.json):

{
  "title": "销售数据探索平台(受限)",
  "description": "仅 root 可访问的实例级权限实测",
  "allow": {
    "id": "root"
  },
  "databases": {
    "sales": {
      "tables": {
        "orders": {
          "allow": {
            "id": "root"
          }
        }
      }
    }
  }
}
  • 实例级 "allow": {"id": "root"}:只有 actor id 为 root 的访问者能看整个实例;
  • 表级再对 orders 单独加一层同样的限制。

用 --root 启动实例,启动日志会打印一次性 root 登录链接(实测输出):

/opt/datasette/venv/bin/datasette sales.db inventory.db -m metadata-private.json --root --port 8007
http://127.0.0.1:8007/-/auth-token?token=edf07de63a4b9a1835e043428495fb31858fd7805c7e143ee741f952f82e0e37

未登录访问首页,被权限块拦截(实测):

curl -s -o /dev/null -w "http_code=%{http_code}\n" http://127.0.0.1:8007/
http_code=403

返回的 HTML 错误页明确标注被拒的权限名(实测节选):

<h1>Forbidden</h1>
<div style="padding: 1em; margin: 1em 0; border: 3px solid red;">view-instance</div>

用启动日志里的 token 链接登录(设置签名 cookie),再访问即放行:

curl -s -c /tmp/cj -o /dev/null -w "auth-token http_code=%{http_code}\n" "http://127.0.0.1:8007/-/auth-token?token=edf07de63a4b9a1835e043428495fb31858fd7805c7e143ee741f952f82e0e37"
curl -s -b /tmp/cj -o /dev/null -w "homepage http_code=%{http_code}\n" http://127.0.0.1:8007/
curl -s -b /tmp/cj http://127.0.0.1:8007/-/actor.json
curl -s -b /tmp/cj -o /dev/null -w "orders.json http_code=%{http_code}\n" "http://127.0.0.1:8007/sales/orders.json?_size=1"
auth-token http_code=302
homepage http_code=200
{"actor": {"id": "root"}}
orders.json http_code=200

解读:/-/auth-token 返回 302 并种下签名 cookie(签名密钥来自 DATASETTE_SECRET 环境变量或 --secret);登录后 /-/actor.json 显示当前身份为 root,表级限制同步放行。需要更丰富的账号体系时,用 datasette-auth-passwords、datasette-auth-github 等插件替换「root 单用户」模式。

八、配置目录模式与 datasette.yaml 的边界(排障实录)

把目录而不是 .db 文件传给 datasette serve 即进入配置目录模式:目录内的全部 .db 自动挂载,settings.json、metadata.json、plugins/、templates/、static/ 自动识别——安装篇《Ubuntu 22.04 安装 Datasette 0.65.5 指南》的 systemd 实例用的正是这个模式。

但实测发现一个版本边界问题,排查过程如下:

  1. 现象:在目录里放一份 datasette.yaml(内容为 settings 与 databases/queries 配置),启动后查询 /-/metadata.json 返回 {},表分页仍是默认值 100 行,yaml 里定义的预定义查询访问返回 404:
curl -s http://127.0.0.1:8005/-/metadata.json
curl -s http://127.0.0.1:8005/sales/orders.json | python3 -c "import json,sys;print('rows:',len(json.load(sys.stdin)['rows']))"
curl -s http://127.0.0.1:8005/sales/status_summary.json
{}
rows: 100
{"ok": false, "error": "Table not found", "status": 404, "title": null}
  1. 对照实验:同一目录内容,把设置改放 settings.json({"default_page_size": 7})再启动:
curl -s http://127.0.0.1:8011/sales/customers.json | python3 -c "import json,sys;print('rows:',len(json.load(sys.stdin)['rows']))"
rows: 7

settings.json 立即生效,而 datasette.yaml 被静默忽略。

  1. 结论:datasette.yaml 统一配置文件是 Datasette 1.0 alpha 系列引入的格式;0.65.x 稳定版只认 metadata.json(或 metadata.yaml)+ settings.json。在稳定版上照抄 alpha 文档的 yaml 写法不会有任何报错提示,配置静默失效——务必确认所读文档版本与所装版本一致。

九、命令行参数与配置的组合拳

两个常用启动参数与配置文件的组合实测。

9.1 --setting 临时覆盖

调试或临时评估时不必改文件,直接命令行覆盖(优先级见第三节实测):

/opt/datasette/venv/bin/datasette sales.db inventory.db --host 127.0.0.1 --port 8002 --setting default_page_size 3
curl -s http://127.0.0.1:8002/sales/customers.json | python3 -c "import json,sys;print('customers rows:',len(json.load(sys.stdin)['rows']))"
customers rows: 3

9.2 --cors 开放跨域

供前端页面直接调用 JSON API 时加 --cors:

/opt/datasette/venv/bin/datasette sales.db inventory.db --host 127.0.0.1 --port 8002 --cors --setting default_page_size 3
curl -s -I "http://127.0.0.1:8002/sales/orders.json?_size=1" | grep -i "access-control\|HTTP/"
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Authorization
Access-Control-Expose-Headers: Link

响应头带 Access-Control-Allow-Origin: *,浏览器跨域 fetch 不再被拦。

9.3 --static 挂载静态目录

把自定义 CSS/图片/说明文件挂到 URL 路径下:

/opt/datasette/venv/bin/datasette sales.db --host 127.0.0.1 --port 8003 --static assets:/srv/datasette/app/static
curl -s -o /dev/null -w "GET /assets/hello.txt http_code=%{http_code}\n" http://127.0.0.1:8003/assets/hello.txt
curl -s http://127.0.0.1:8003/assets/hello.txt
GET /assets/hello.txt http_code=200
Datasette 静态资源实测:由 --static 挂载提供。

⚠️ 排障实录:挂载点按文件路径生效——访问 /assets/ 目录本身会返回 404(Database not found),必须带完整文件名(/assets/hello.txt)。排障时先用 -o /dev/null -w 看状态码再怀疑配置。

十、生产配置模板

适用场景:4GB 内存、NVMe SSD、面向公众的只读数据发布站(日 PV 万级),systemd 托管 + nginx 反代。

/srv/datasette/app/settings.json:

{
  "default_page_size": 50,
  "max_returned_rows": 1000,
  "sql_time_limit_ms": 1000,
  "num_sql_threads": 4,
  "default_cache_ttl": 3600,
  "allow_download": false,
  "allow_csv_stream": true,
  "max_csv_mb": 50,
  "default_allow_sql": false,
  "force_https_urls": true,
  "template_debug": false,
  "trace_debug": false
}

要点解读:default_cache_ttl 拉到 3600 秒让 CDN/浏览器扛住重复流量;default_allow_sql: false 关掉自由 SQL(业务查询一律走 metadata 的预定义查询发布);allow_download: false 不暴露原始库文件;force_https_urls: true 配合 nginx 终止 TLS 保证 API 输出链接协议正确。

/srv/datasette/app/metadata.json 最小骨架:

{
  "title": "数据发布站",
  "source": "数据来源单位",
  "source_url": "https://data.example.com/",
  "license": "CC BY 4.0",
  "license_url": "https://creativecommons.org/licenses/by/4.0/",
  "databases": {
    "sales": {
      "description": "销售数据",
      "queries": {
        "daily_summary": {
          "title": "每日汇总",
          "sql": "select created_at, count(*) as c from orders group by created_at order by created_at desc"
        }
      }
    }
  }
}

改完两个文件后 sudo systemctl restart datasette 生效(配置目录模式无热加载,见第三节排障实录)。

十一、常见问题(FAQ)

Q1:改了 settings.json / metadata.json 为什么不生效? 0.65.5 配置目录模式不热加载配置文件,必须 sudo systemctl restart datasette(或重启进程)。验证方法:curl -s http://127.0.0.1:8001/-/metadata.json 看描述是否更新。

Q2:datasette.yaml 放进目录怎么没反应,也不报错? 该文件是 1.0 alpha 的配置格式,0.65.x 静默忽略(见第八节对照实验)。稳定版请用 settings.json + metadata.json。

Q3:?_size= 调大就 400? 受 max_returned_rows 钳制,报错文案会直接告诉你上限(如 _size must be <= 200)。确实需要全量导出时用 .csv?_stream=1(受 allow_csv_stream 与 max_csv_mb 约束)。

Q4:SQL 查询框想只对内部开放? settings.json 设 "default_allow_sql": false 并重启;已发布的预定义查询不受影响。

Q5:怎么确认某个 setting 当前生效值? 访问 /-/settings.json 端点可直接查看实例当前全部 settings 的生效值与来源,比翻配置文件更可靠。

十二、参考链接