跳转到主要内容

提供SQLite数据库自动GraphQL API的Datasette插件

项目描述

datasette-graphql

PyPI Changelog Tests License

提供SQLite数据库自动GraphQL API的Datasette插件

了解此项目的更多信息: 使用新的datasette-graphql插件在Datasette中实现GraphQL

datasette-graphql-demo.datasette.io/graphql 尝试实时演示

GraphiQL animated demo

安装

在Datasette相同的环境中安装此插件。

$ datasette install datasette-graphql

配置

默认情况下,此插件将在/graphql处添加GraphQL API。您可以使用path插件设置配置不同的路径,例如,通过将以下内容添加到metadata.json

{
  "plugins": {
    "datasette-graphql": {
      "path": "/-/graphql"
    }
  }
}

这将设置GraphQL API以在/-/graphql处运行。

使用

此插件将/graphql设置为第一个附加数据库的GraphQL端点。

如果您有多个附加数据库,每个数据库都将有自己的端点/graphql/数据库名称

自动生成的GraphQL模式在/graphql/数据库名称.graphql处可用 - 这里是一个示例

查询表和列

可以像这样查询单个表(以及SQL视图)

{
  repos {
    nodes {
      id
      full_name
      description_
    }
  }
}

尝试此查询

在此示例查询中,底层数据库表名为repos,其列包括idfull_namedescription。由于description是一个保留字,因此查询需要请求description_

获取单个记录

如果您只想获取一条记录——例如,如果您想通过其主键获取一行——则可以使用tablename_row字段

{
  repos_row(id: 107914493) {
    id
    full_name
    description_
  }
}

尝试此查询

tablename_row字段接受主键列(或列)作为参数。它也支持与下面描述的tablename字段相同的filter:search:sort:sort_desc:参数。

访问嵌套对象

如果某列是另一个表的外键,您可以使用如下嵌套查询请求该外键指向的表中的列

{
  repos {
    nodes {
      id
      full_name
      owner {
        id
        login
      }
    }
  }
}

尝试此查询

访问相关对象

如果另一个表有一个外键指向您正在访问的表,您可以从该相关表获取行。

考虑一个users表,它与repos相关——一个仓库有一个外键指向拥有该仓库的用户。users对象类型将有一个repos_by_owner_list字段,可以用来访问这些相关仓库

{
  users(first: 1, search: "simonw") {
    nodes {
      name
      repos_by_owner_list(first: 5) {
        totalCount
        nodes {
          full_name
        }
      }
    }
  }
}

尝试此查询

过滤表

您可以使用filter:参数来过滤特定表返回的行。这个参数接受一个将列映射到操作的过滤器对象。例如,返回只有Apache 2许可证并且有超过10个星级的存储库

{
  repos(filter: {license: {eq: "apache-2.0"}, stargazers_count: {gt: 10}}) {
    nodes {
      full_name
      stargazers_count
      license {
        key
      }
    }
  }
}

尝试此查询

有关更多操作,请参阅表过滤器示例,以及Datasette文档中的列过滤器参数的详细信息。

这些相同的过滤器也可以用于嵌套关系,如下所示

{
  users_row(id: 9599) {
    name
    repos_by_owner_list(filter: {name: {startswith: "datasette-"}}) {
      totalCount
      nodes {
        full_name
      }
    }
  }
}

尝试此查询

当您要表达的内容过于复杂,无法用过滤器表达式建模时,可以使用where:参数作为filter:的替代。它接受一个字符串片段SQL,该片段将被包含在SQL查询的WHERE子句中。

{
  repos(where: "name='sqlite-utils' or name like 'datasette-%'") {
    totalCount
    nodes {
      full_name
    }
  }
}

尝试此查询

排序

您可以使用sort:sort_desc:参数为表的结果设置排序顺序。此参数的值应该是您希望按其排序(或降序排序)的列名。

{
  repos(sort_desc: stargazers_count) {
    nodes {
      full_name
      stargazers_count
    }
  }
}

尝试此查询

分页

默认情况下,将返回前10行。您可以使用first:参数来控制这一点。

{
  repos(first: 20) {
    totalCount
    pageInfo {
      hasNextPage
      endCursor
    }
    nodes {
      full_name
      stargazers_count
      license {
        key
      }
    }
  }
}

尝试此查询

totalCount字段返回与查询匹配的记录总数。

请求pageInfo.endCursor字段可以为您提供请求下一页所需的价值。您可以将其传递给after:参数以请求下一页。

{
  repos(first: 20, after: "134874019") {
    totalCount
    pageInfo {
      hasNextPage
      endCursor
    }
    nodes {
      full_name
      stargazers_count
      license {
        key
      }
    }
  }
}

尝试此查询

hasNextPage字段告诉您是否还有更多记录。

搜索

如果已配置表使用SQLite全文搜索,您可以使用search:参数执行对其的搜索

{
  repos(search: "datasette") {
    totalCount
    pageInfo {
      hasNextPage
      endCursor
    }
    nodes {
      full_name
      description_
    }
  }
}

尝试此查询

可以使用sqlite-utils Python库和CLI工具将全文搜索添加到现有的数据库表。

包含JSON字符串的列

如果您的表有一个包含作为JSON编码的数据的列,datasette-graphql将使该列作为编码的JSON字符串可用。调用您的API的客户端需要将字符串解析为JSON才能访问数据。

您可以通过将列配置为JSON列来以嵌套结构返回数据。在metadata.json中的配置如下

{
    "databases": {
        "test": {
            "tables": {
                "repos": {
                    "plugins": {
                        "datasette-graphql": {
                            "json_columns": [
                                "tags"
                            ]
                        }
                    }
                }
            }
        }
    }
}

自动camelCase

您的列和表的名称默认与GraphQL中的表示匹配。

如果您有names_like_this格式的表,您可能希望在GraphQL中使用namesLikeThis来与GraphQL和JavaScript约定保持一致。

您可以通过在metadata.json中使用"auto_camelcase"插件配置设置来打开自动camelCase。

{
    "plugins": {
        "datasette-graphql": {
            "auto_camelcase": true
        }
    }
}

CORS

此插件遵循传递给 datasette 命令行工具的 --cors 选项。如果您传递了 --cors,它将添加以下 CORS HTTP 头,以允许在其它域上运行的 JavaScript 访问 GraphQL API

access-control-allow-headers: content-type
access-control-allow-method: POST
access-control-allow-origin: *

执行限制

插件默认实现两个限制

  • 构成 GraphQL 执行的所有底层 SQL 查询的总执行时间必须不超过 1000ms(一秒)
  • 由于嵌套 GraphQL 字段而执行的 SQL 表查询总数不得超过 100

可以使用 num_queries_limittime_limit_ms 插件配置设置来自定义这些限制,例如在 metadata.json

{
    "plugins": {
        "datasette-graphql": {
            "num_queries_limit": 200,
            "time_limit_ms": 5000
        }
    }
}

将它们设置为 0 将完全禁用限制检查。

graphql()模板函数

插件还提供了一个名为 graphql() 的 Jinja 模板函数。您可以在 Datasette 的 自定义模板 中使用该函数,如下所示

{% set users = graphql("""
{
    users {
        nodes {
            name
            points
            score
        }
    }
}
""")["users"] %}
{% for user in users.nodes %}
    <p>{{ user.name }} - points: {{ user.points }}, score = {{ user.score }}</p>
{% endfor %}

该函数将执行针对生成的模式的 GraphQL 查询并返回结果。您可以将这些结果分配给模板中的一个变量,然后遍历并显示它们。

默认情况下,查询将针对第一个附加的数据库运行。您可以使用函数的可选第二个参数来指定不同的数据库 - 例如,要针对附加的 github.db 数据库运行,您将这样做

{% set user = graphql("""
{
    users_row(id:9599) {
        name
        login
        avatar_url
    }
}
""", "github")["users_row"] %}

<h1>Hello, {{ user.name }}</h1>

您可以通过传递到 variables= 参数中,在模板调用中使用 GraphQL 变量

{% set user = graphql("""
query ($id: Int) {
    users_row(id: $id) {
        name
        login
        avatar_url
    }
}
""", database="github", variables={"id": 9599})["users_row"] %}

<h1>Hello, {{ user.name }}</h1>

使用插件添加自定义字段

datasette-graphql 为 Datasette 添加了一个新的 插件钩子,可用于向您的 GraphQL 模式添加自定义字段。

插件钩子如下所示

@hookimpl
def graphql_extra_fields(datasette, database):
    "A list of (name, field_type) tuples to include in the GraphQL schema"

您可以使用此钩子返回一个描述应公开在您模式中的附加字段的元组的列表。每个元组应包含一个命名新字段的字符串,以及一个指定模式和提供 resolver 函数的 Graphene 字段对象

此示例实现使用 pkg_resources 返回当前安装的 Python 包列表

import graphene
from datasette import hookimpl
import pkg_resources


@hookimpl
def graphql_extra_fields():
    class Package(graphene.ObjectType):
        "An installed package"
        name = graphene.String()
        version = graphene.String()

    def resolve_packages(root, info):
        return [
            {"name": d.project_name, "version": d.version}
            for d in pkg_resources.working_set
        ]

    return [
        (
            "packages",
            graphene.Field(
                graphene.List(Package),
                description="List of installed packages",
                resolver=resolve_packages,
            ),
        ),
    ]

安装此插件后,可以使用以下 GraphQL 查询检索安装包列表

{
  packages {
    name
    version
  }
}

开发

要本地设置此插件,首先检出代码。然后创建一个新的虚拟环境

cd datasette-graphql
python3 -mvenv venv
source venv/bin/activate

或者如果您正在使用 pipenv

pipenv shell

现在安装依赖项和测试

pip install -e '.[test]'

要运行测试

pytest

项目详细信息


下载文件

下载适用于您平台的应用程序。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分布

datasette-graphql-2.2.tar.gz (287.7 kB 查看哈希值)

上传时间

构建分布

datasette_graphql-2.2-py3-none-any.whl (278.4 kB 查看哈希值)

上传时间 Python 3

由以下提供支持