Supabase PG_GraphQL 技术解析:从SQL表到GraphQL API的自动映射

Supabase PG_GraphQL 技术解析:从SQL表到GraphQL API的自动映射

pg_graphql GraphQL support for PostgreSQL pg_graphql 项目地址: https://gitcode.com/gh_mirrors/pg/pg_graphql

概述

Supabase PG_GraphQL 是一个强大的工具,它能够自动将PostgreSQL数据库表结构映射为GraphQL API。本文将深入解析这一映射过程的核心机制,帮助开发者理解如何通过GraphQL高效地操作PostgreSQL数据库。

基础映射原理

表到类型的转换

PG_GraphQL的核心功能是将SQL表自动转换为GraphQL类型:

  • 表名映射:每个PostgreSQL表都会生成对应的GraphQL类型,默认情况下表名直接转换为类型名(如account_holder表对应account_holder类型)
  • 字段映射:表中的列和关系(外键)会转换为类型的字段

对于使用snake_case命名规范的SQL实体,可以启用名称转换功能,将表名和字段名转换为更符合GraphQL/JavaScript的命名风格(如account_holderAccountHolder

主键要求

每个表必须定义主键才能暴露在GraphQL模式中。例如:

-- 会被暴露,因为有主键
create table "Blog"(
  id serial primary key,
  name varchar(255) not null
);

-- 不会被暴露,因为没有主键
create table "BlogNoPK"(
  id int,
  name varchar(255) not null
);

查询类型详解

Node接口

node接口是GraphQL API的重要入口点,它允许通过全局唯一的nodeId字段检索记录:

type Query {
  node(nodeId: ID!): Node
}

使用示例:

{
  node(nodeId: "WyJwdWJsaWMiLCAiYmxvZyIsIDFd") {
    nodeId
    ... on Blog {
      name
      description
    }
  }
}

集合查询

每个表都会在Query类型中生成对应的集合查询入口:

type Query {
  blogCollection(
    first: Int
    last: Int
    before: Cursor
    after: Cursor
    offset: Int
    filter: BlogFilter
    orderBy: [BlogOrderBy!]
  ): BlogConnection
}

集合查询返回连接类型(Connection),支持分页、过滤和排序。

连接类型结构
type BlogConnection {
  totalCount: Int!       # 匹配过滤条件的记录总数
  pageInfo: PageInfo!    # 分页元数据
  edges: [BlogEdge!]!    # 结果集
  aggregate: BlogAggregate # 聚合函数结果
}

type BlogEdge {
  cursor: String!  # 记录的唯一标识符
  node: Blog       # 记录内容
}

type PageInfo {
  startCursor: String
  endCursor: String
  hasNextPage: Boolean!
  hasPreviousPage: Boolean!
}

高级查询功能

聚合函数

聚合功能可以对匹配查询条件的记录集合进行统计计算:

type BlogAggregate {
  count: Int!              # 记录计数
  sum: BlogSumAggregateResult  # 求和
  avg: BlogAvgAggregateResult  # 平均值
  min: BlogMinAggregateResult  # 最小值
  max: BlogMaxAggregateResult  # 最大值
}

使用示例:

{
  blogCollection(filter: {rating: {gt: 3}}) {
    aggregate {
      count
      sum { rating visits }
      avg { rating }
      min { createdAt title }
      max { rating updatedAt }
    }
  }
}

分页机制

PG_GraphQL支持两种分页方式:

1. 基于游标的分页

遵循Relay规范,使用first/lastafter/before参数:

{
  blogCollection(
    first: 2,
    after: "WzJd"  # 上一页的endCursor
  ) {
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      node { id name }
    }
  }
}
2. 基于偏移量的分页

使用firstoffset参数,类似于SQL的LIMIT和OFFSET:

{
  blogCollection(
    first: 2,
    offset: 2
  ) {
    edges {
      node { id name }
    }
  }
}

注意:偏移量分页在大偏移量时性能较差,推荐优先使用游标分页。

过滤功能

通过filter参数可以对结果集进行筛选:

input BlogFilter {
  id: IntFilter
  name: StringFilter
  description: StringFilter
  tags: StringListFilter
  createdAt: DatetimeFilter
  and: [BlogFilter!]
  or: [BlogFilter!]
  not: BlogFilter
}

支持多种过滤操作符:

| 操作符 | 描述 | 适用类型 | |------------|-----------------------------|---------------------| | eq | 等于 | 所有类型 | | neq | 不等于 | 所有类型 | | gt/gte | 大于/大于等于 | 数值、字符串、日期时间 | | lt/lte | 小于/小于等于 | 数值、字符串、日期时间 | | in | 在值列表中 | 所有类型 | | is | 是NULL/NOT NULL | 所有类型 | | startsWith | 以指定字符串开头 | 字符串 | | like/ilike | 模式匹配(区分/不区分大小写) | 字符串 | | regex | 正则表达式匹配 | 字符串 | | contains | 包含(用于数组列) | 数组类型 |

使用示例:

{
  blogCollection(
    filter: {
      rating: { gt: 3 },
      or: [
        { name: { ilike: "%graphql%" } },
        { tags: { contains: ["database"] } }
      ]
    }
  ) {
    edges {
      node { id name rating }
    }
  }
}

总结

Supabase PG_GraphQL提供了从PostgreSQL到GraphQL的完整映射方案,包括:

  1. 自动类型生成:将表结构转换为GraphQL类型
  2. 丰富的查询功能:支持节点查询、集合查询
  3. 高级数据操作:聚合、分页、过滤等
  4. 灵活的命名控制:支持名称转换和手动覆盖

这些特性使得开发者能够以GraphQL的方式高效地操作PostgreSQL数据库,同时保持对数据模型的完全控制。

pg_graphql GraphQL support for PostgreSQL pg_graphql 项目地址: https://gitcode.com/gh_mirrors/pg/pg_graphql

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何蒙莉Livia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值