一个基于 Postgres 的简易 low-code / nocode 表格服务,支持:
- Type:列类型定义
- Table:动态创建/删除逻辑表
- Column:按列增删改(底层 ALTER TABLE)
- Row/Cell:创建/更新/删除单行和批量行
- Index:按列创建/删除索引
- Relationship:虚拟列类型,支持一对多、多对一/一对一;ListRows 时可指定
expand_column_ids带出子表/关联表数据 - 同时支持 gRPC 与 HTTP(JSON)(通过 grpc-gateway)
- 支持 单库模式 与 多租户(数据库级隔离)模式
- Go 1.22+
- protoc(Protocol Buffers 编译器)
- protoc 插件:
protoc-gen-goprotoc-gen-go-grpcprotoc-gen-grpc-gateway
- 一个可访问的 Postgres 实例
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest确保 $GOBIN(或者 $GOPATH/bin)在 PATH 中。
在项目根目录执行:
make proto生成的代码会放到 gen/ 目录下(与 proto/ 中的包路径一致)。
使用固定数据库(例如 tables):
export TENANT_MODE=single
export SINGLE_DATABASE_URL='postgresql://postgres:[email protected]:5432/tables'
# 或者使用 DATABASE_URL(当 SINGLE_DATABASE_URL 未设置时)
# export DATABASE_URL='postgresql://postgres:[email protected]:5432/tables'
make run服务启动后:
- gRPC 监听:
localhost:9090 - HTTP(grpc-gateway + 静态页面):
http://localhost:8080/
每个租户使用一个独立的 Postgres 数据库,例如连接串为:
postgresql://postgres:[email protected]:5432/<tenant_id>
配置环境变量:
export TENANT_MODE=multi
export TENANT_DSN_TEMPLATE='postgresql://postgres:[email protected]:5432/%s'
make run访问时在 HTTP 头或 gRPC metadata 中带上租户 ID:
- HTTP 头:
X-Tenant-Id: tenant_a - 将自动连接到:
postgresql://postgres:[email protected]:5432/tenant_a
每个租户数据库都会独立创建自身的:
lc_typeslc_tableslc_columnslc_indexes
项目内置了一个简单的 HTML 测试页:
- 路径:
static/index.html - 访问地址:
http://localhost:8080/
功能:
- 创建 Table
- 为 Table 添加 Column
- 根据列信息生成表单并创建 Record(Row)
如果在多租户模式下测试,可以使用浏览器开发者工具或自行扩展该页面,在每次 fetch 请求中添加 X-Tenant-Id 头。
列类型可为 relationship(虚拟列,无实际 PG 列)。列 config 约定:
-
一对多(当前表为主表,子表多行指向当前行)
target_table_id:子表 idlink_column_id:子表中「存当前行 id」的外键列 id- 查询时按「子表. link 列 = 当前行 id」查出所有子行
-
多对一 / 一对一(当前表存外键指向目标表)
target_table_id:目标表 idtarget_column_id:当前表中存目标行 id 的列 id- 查询时用当前行该列的值作为目标表
id查一条
ListRows 支持 expand_column_ids(relationship 列 id 列表)。返回的每行 cells 中,对应列的值为 JSON:{ "rows": [ { "id", "cells" }, ... ] },一对多为多元素,一对一为单元素。
HTTP 示例:GET /v1/tables/{table_id}/rows?expand_column_ids=col-uuid-1&expand_column_ids=col-uuid-2
-
生成 proto 对应 Go 代码
make proto
-
启动服务
make run
-
清理生成代码
make clean