PostgreSQL 数据库
CloudBase PostgreSQL 数据库已开放体验,欢迎试用。如需创建体验环境,请联系云开发团队。功能正在持续迭代完善,正式发布时间请关注官方公告。
CloudBase 提供了 PostgreSQL 数据库 服务,基于开源 PostgREST 构建,支持完整的 SQL 功能,并通过 表级 GRANT + 行级 RLS Policy 的双层权限模型,实现客户端可直连数据库的安全访问能力。
阅读前建议先了解 PG 模式概述,明确 PostgreSQL 在 云开发环境中的整体定位。
使用 AI 管理关系型数据库和 SQL 操作
PG 模式:以 PostgreSQL 为中心
CloudBase PostgreSQL 数据库不只是"多了一个数据库选项",它代表了一种以 PostgreSQL 为中心的环境形态——PG 模式。在这种形态下,PostgreSQL 不仅承担业务数据存储,还作为统一基础设施,让账号、权限、云存储元数据都落到同一个数据库内:
- 业务数据:直接存进 PostgreSQL 表,客户端通过 PostgREST 自动暴露的 RESTful API 直连读写
- 权限模型:以 SQL 表达——表级
GRANT+ 行级RLS Policy双层校验,请求自带 JWT 由数据库判定权限 - 账号系统:用户数据存储在
authschema,可以直接用 SQL 查询、关联到业务表 - 云存储:文件元数据存储在
storageschema,权限同样用 RLS 表达,与业务数据共享一套权限语言
这意味着开发者只需掌握 SQL 一套表达方式,就能完成数据建模、权限设计、跨域协作。本章后续文档(快速上手、权限管理、RPC 等)默认就在这个上下文中讨论,不再重复 "PG 模式" 这一前缀。
能力速览
| 能力 | 说明 |
|---|---|
| 完整 SQL | 表、视图、外键、索引、事务、触发器、存储过程、CTE、窗口函数、分区等 |
| PostgREST RESTful API | 表 / 视图 / RPC 自动暴露为 REST 接口,支持筛选、排序、分页、关联查询、嵌套写入 |
| 双层权限 | GRANT(表级) + RLS Policy(行级),双重锁定 |
| 三种访问角色 | anon / authenticated / service_role |
| 扩展生态 | pgvector + vectorscale、tencentdb_ai、zhparser / pg_jieba(中文分词)、TimescaleDB、Apache AGE、PL/V8 等 |
| 身份认证联动 | auth schema + JWT claims 可直接在 SQL 中读取用户身份 |
| 云存储联动 | storage schema 存储对象元数据,可与业务表 JOIN |
如何启用
当您创建 CloudBase PostgreSQL 版本环境时,PostgreSQL 数据库会自动启用,无需手动创建或初始化数据库实例。
访问数据库的三种方式
1. 客户端 SDK(直连 + RLS)
最常用的方式。前端通过云开发 SDK 直接读写数据库,由 RLS 完成鉴权:
import cloudbase from '@cloudbase/js-sdk';
// 选择一种鉴权方式:
// (1) 使用 Publishable Key(前端可见):accessKey 传入即可,所有未显式登录的请求都以 anon 身份访问
const app = cloudbase.init({ env: '<env-id>', accessKey: '<Publishable Key>' });
// (2) 或不传 accessKey,前端调用 auth.signInAnonymously() / signInWithPassword() 等显式登录
// const app = cloudbase.init({ env: '<env-id>' });
// await app.auth.signInAnonymously();
const db = app.rdb();
// 查询(RLS 自动按登录用户过滤)
const { data } = await db
.from('todos')
.select('id, title, is_completed')
.eq('is_completed', false);
// 新增(owner_id 由数据库默认值自动填充为 JWT 的 sub)
await db.from('todos').insert({ title: '写一篇文档' });
⚠️ SDK 请求必须携带 JWT(Publishable Key、access_token 或 API Key 三选一)。未提供时网关会拒绝请求。
云开发提供了多种 SDK 供开发者操作 PostgreSQL 数据库:
| SDK 类型 | 适用平台 |
|---|---|
| 小程序 ClientSDK | 小程序 |
| JS SDK | Web 浏览器 |
| Node SDK | Node.js 环境 |
| HTTP API | 通用 |
小程序 ClientSDK 获取 db 实例后,操作 PostgreSQL 数据库语法与 Web JS SDK 一致,具体语法请参考 JS SDK。
2. REST API(PostgREST 规范)
适用于无 SDK 场景(其他后端、低代码平台、第三方系统)。
基础端点:
REST: https://<envId>.api.tcloudbasegateway.com/v1/rdb/rest/<table>
Auth: https://<envId>.api.tcloudbasegateway.com/auth/v1
认证头: Authorization: Bearer <Publishable Key | access_token | API Key>
调用示例:
# 列出商品(匿名,使用 Publishable Key)
curl "https://<envId>.api.tcloudbasegateway.com/v1/rdb/rest/products?select=id,name,price&order=price.desc" \
-H "Authorization: Bearer <Publishable Key>"
# 登录后下单(使用 access_token)
curl -X POST "https://<envId>.api.tcloudbasegateway.com/v1/rdb/rest/orders" \
-H "Authorization: Bearer <access_token>" \
-H "Prefer: return=representation" \
-H "Content-Type: application/json" \
-d '{"product_id":1,"quantity":2,"total_price":199.00}'
详见 HTTP API - PostgREST RESTful API。
3. 云 API ExecutePGSql(管控面)
云 API ExecutePGSql 是管理员执行任意 SQL 的能力,常用于 CI/CD 自动化部署、数据库 schema 迁移、自动化建表等场景。
基本信息:
| 字段 | 值 |
|---|---|
| 接口名称 | ExecutePGSql |
| 端点 | tcb.tencentcloudapi.com |
| Version | 2018-06-08 |
| Region | 必填,与环境所在地域一致(如 ap-shanghai) |
| 签名方式 | TC3-HMAC-SHA256 |
请求体:
{
"EnvId": "<envId>",
"Sql": "<要执行的 SQL>",
"Role": "<可选,以指定的数据库角色执行;常用值:anon / authenticated / service_role>"
}
Role参数可省略:
- 省略时:以系统超级管理员角色
cloudbase_admin执行,具备SUPERUSER+BYPASSRLS权限,可执行任意 DDL(包括CREATE TABLE等结构变更)和绕过所有 RLS 策略- 指定
Role后(常用值:anon/authenticated/service_role):以指定角色执行 SQL,便于在管控面模拟特定角色调试 RLS 策略,验证策略是否符合预期。注意此时受 GRANT + RLS 约束
关于 DDL 语句:部分 DDL(CREATE / ALTER / DROP / GRANT / REVOKE / TRUNCATE / COMMENT 等)在通过 ExecutePGSql 直接执行时可能返回 InternalError。遇到失败时,可将该 DDL 包装为匿名代码块重试:
-- 直接执行可能报错的 DDL
CREATE TABLE public.products (id serial PRIMARY KEY, name text);
-- 失败时包装为 DO $$ 代码块重试
DO $$ BEGIN EXECUTE 'CREATE TABLE public.products (id serial PRIMARY KEY, name text)'; END $$;
SQL 中的单引号
'在EXECUTE '...'内需转义为''。
Python 示例(使用腾讯云 SDK):
pip install tencentcloud-sdk-python
import json, re
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.tcb.v20180608 import tcb_client, models
SECRET_ID = "<your SecretId>"
SECRET_KEY = "<your SecretKey>"
ENV_ID = "<your envId>"
REGION = "ap-shanghai"
_DDL_KEYWORDS = re.compile(
r"^\s*(CREATE|DROP|ALTER|GRANT|REVOKE|TRUNCATE|COMMENT|"
r"SET|RESET|LOCK|REINDEX|CLUSTER|VACUUM|ANALYZE)\b",
re.IGNORECASE,
)
def _wrap_ddl(sql: str) -> str:
return f"DO $$ BEGIN EXECUTE '{sql.replace(chr(39), chr(39)*2)}'; END $$"
def execute_sql(sql: str, role: str = None, retry_with_wrap: bool = True) -> dict:
cred = credential.Credential(SECRET_ID, SECRET_KEY)
http_profile = HttpProfile()
http_profile.endpoint = "tcb.tencentcloudapi.com"
client_profile = ClientProfile()
client_profile.httpProfile = http_profile
client = tcb_client.TcbClient(cred, REGION, client_profile)
body = {"EnvId": ENV_ID, "Sql": sql}
if role:
body["Role"] = role
try:
req = models.ExecutePGSqlRequest()
req.from_json_string(json.dumps(body))
return json.loads(client.ExecutePGSql(req).to_json_string())
except Exception as e:
# 部分 DDL 直接执行会失败,自动用 DO $$ 包装重试
if retry_with_wrap and _DDL_KEYWORDS.match(sql.strip()):
return execute_sql(_wrap_ddl(sql), role=role, retry_with_wrap=False)
raise
# DML 直接执行
print(execute_sql("SELECT 1"))
# DDL 自动重试(失败时用 DO $$ 包装)
execute_sql("""
CREATE TABLE public.products (
id serial PRIMARY KEY,
name text NOT NULL,
price numeric(10,2) NOT NULL
)
""")
execute_sql("ALTER TABLE public.products ENABLE ROW LEVEL SECURITY")
execute_sql("GRANT SELECT ON public.products TO anon")
- 每次 API 调用只能执行一条 SQL,不能用分号拼接多条;批量执行请按行/分号拆分后逐条调用
- DDL 失败时使用
DO $$ BEGIN EXECUTE '...'; END $$包装;注意单引号转义 - API 偶尔可能因后端短暂故障返回
InternalError,建议加入指数退避重试 - 本接口属于管理员操作,权限高,仅在后端使用,不要暴露 SecretKey
双层权限模型
数据库权限由两层组成,请求两层都通过才会成功:
请求 → JWT 解析 → 第一层:表级 GRANT(能执行哪些操作)
→ 第二层:RLS Policy(能访问哪些行)→ 返回结果
第一层:GRANT
-- 示例:匿名可读,登录用户可读写,管理员全部权限
GRANT SELECT ON public.orders TO anon;
GRANT SELECT, INSERT, UPDATE, DELETE ON public.orders TO authenticated;
GRANT ALL ON public.orders TO service_role;
-- 使用 serial 主键时,还需授予序列权限
GRANT USAGE, SELECT ON SEQUENCE public.orders_id_seq TO authenticated;
第二层:RLS Policy
ALTER TABLE public.orders ENABLE ROW LEVEL SECURITY;
-- 匿名用户可见:仅公开订单(示例)
CREATE POLICY orders_anon_select ON public.orders
FOR SELECT TO anon
USING (is_public = true);
-- 登录用户可见:仅自己的
CREATE POLICY orders_auth_select ON public.orders
FOR SELECT TO authenticated
USING (buyer_id = (current_setting('request.jwt.claims', true)::json->>'sub'));
service_role由于具备 BYPASSRLS,自动绕过 RLS Policy。只要在第一层 GRANT 了对应权限即可,无需为它写 Policy。
四种常见 RLS 模式
以下四种模式覆盖绝大多数业务场景,可以直接复用(命名沿袭传统模式云存储的同名权限模式,便于心智迁移):
| 模式 | 典型场景 | 权限效果 |
|---|---|---|
READONLY | 博客文章、产品目录 | 所有人可读,仅创建者可写 |
PRIVATE | 私人笔记、个人设置 | 仅创建者可读写(用户间完全隔离) |
ADMINWRITE | 公告、系统配置 | 所有人可读,仅管理员可写 |
ADMINONLY | 审计日志、后台配置 | 仅管理员可读写 |
复杂场景(多租户 SaaS 协作、社交可见性、可见性跟随帖子等)可通过子查询 / EXISTS / OR 条件灵活表达。
查询表达式(PostgREST 约定)
REST API 支持丰富的查询参数:
# 过滤
?category=eq.电子产品 # 精确匹配
?price=gte.1000&price=lte.5000 # 范围
?name=like.*iPhone* # 模糊
?status=in.(pending,paid) # IN
# 排序
?order=price.desc
?order=category.asc,price.desc
# 分页
?limit=10&offset=0
# 列选择
?select=id,name,price
# 关联查询(基于外键自动推断)
?select=*,products(name,price) # 订单 + 关联商品
常见报错处理
xxx.rdb is not a function
报错原因:当前使用的 CloudBase SDK 版本过旧,不支持 PostgreSQL 数据库操作。
解决方法:更新当前 SDK 到最新版本。
Generating default gateway base url failed: env not found
报错原因:微信基础库版本过低,不支持云开发 PostgreSQL 数据库功能。
解决方法:更新微信基础库到 3.8.9 版本以上。
在微信开发者工具中设置最低基础库版本:
- 打开「项目详情」
- 在「本地设置」中,将「调试基础库」设置为 3.8.9 或更高版本
- 在「基本信息」中,将「最低基础库版本」设置为 3.8.9 或更高版本
更新基础库版本后,请确保小程序在低版本微信中的兼容性处理,或在小程序管理后台设置最低版本要求。
最佳实践与常见陷阱
推荐做法:
- 业务表归属字段使用
DEFAULT绑定 JWTsub,禁止前端传入 - UPDATE 策略同时设置
USING和WITH CHECK - GRANT + RLS 双重锁定:不希望某角色写就在 GRANT 层拦截
- 使用
serial/bigserial主键时别忘记授予SEQUENCE的权限 - 清理测试数据时注意外键顺序:先删子表再删父表
常见陷阱:
- 启用 RLS 后忘记建 Policy → 所有非
service_role请求都被拒 - 建了 Policy 但没 GRANT → 表级权限不通过
- 前端暴露 API Key →
service_roleBYPASSRLS,所有数据暴露 - UPDATE 只写了
USING未写WITH CHECK→ 用户可以通过 UPDATE 篡改归属字段"窃取"数据 - 对匿名用户授予过多权限(除非有强诉求,
anon只给SELECT)
详细文档入口
- 基础权限管理
- RLS 权限模式库
- 数据库函数(RPC)
- 外键管理
- 索引管理
- HTTP API - PostgREST RESTful API
- Web SDK - PostgreSQL 数据库
- Node.js SDK - PostgreSQL 数据库