A Protobuf (proto3 and buf v2) schema definition for PostgreSQL, enabling type-safe database schema generation through protocol buffers. This package provides comprehensive PostgreSQL type support, validation, and platform-specific deployment options.
- Postgres Proto Schema
- Define PostgreSQL schemas using protocol buffers with:
- Rich Type System: Comprehensive PostgreSQL types with detailed configuration options
- Table Configuration: Names, schemas, indexes, constraints, RLS policies, partitioning
- Column Configuration: Type-specific options, constraints, collation
- Platform Support: Deployment options for major PostgreSQL platforms (RDS, Aurora, etc.)
- Built-in Patterns: Support for timestamps and audit tracking
- Validation: Built-in field validation using buf validate
This package can be used in three ways:
Use the proto files directly through the Buf Schema Registry:
# buf.yaml
version: v1
deps:
- buf.build/zackiles/postgres-proto-schema
- buf.build/bufbuild/protovalidate # Required for field validation rules
Import the proto files in your schema:
import "postgres_proto_schema/v1/schema.proto"; // Main entrypoint
import "buf/validate/validate.proto"; // For validation rules
The proto files are also available directly on GitHub.
We provide pre-compiled code for Go and TypeScript and Javascript. At the moment we don't publish npm or go mods, but will soon! You can copy the files to your project source to include them manually for now:
- For the TypeScript and Javascript SDKs:
# Ran in your project workspace. Copies to ./src/postgres-proto-schema
git clone --depth 1 --filter=blob:none --sparse https://github.com/zackiles/postgres-proto-schema ./src/postgres-proto-schema && cd ./src/postgres-proto-schema && git sparse-checkout set gen/ts
# Then import. Example:
# import * as Schema from './src/postgres-proto-schema/gen/ts/schema_pb.js (or .ts/.d.ts)'
# Node, you'll need to npm install @bufbuild/protobuf to use this SDK.
- For the Go SDK:
# Ran in your project workspace. Copies to ./internal/postgres-proto-schema
git clone --depth 1 --filter=blob:none --sparse https://github.com/zackiles/postgres-proto-schema ./internal/postgres-proto-schema && cd ./internal/postgres-proto-schema && git sparse-checkout set gen/go
# Then import it. Example:
# import "myproject/internal/postgres-proto-schema/v1"
Generate code for your preferred language using buf:
# buf.gen.yaml
version: v1
plugins:
- plugin: go
out: gen/go
opt: paths=source_relative
- plugin: typescript
out: gen/ts
opt: paths=source_relative
Then run:
buf generate
The package provides a comprehensive set of PostgreSQL types through the Type
enum:
Category | Types |
---|---|
Basic | TYPE_TEXT , TYPE_INTEGER , TYPE_BIGINT , TYPE_BOOLEAN , TYPE_TIMESTAMP , TYPE_TIMESTAMPTZ , TYPE_UUID , TYPE_JSONB , TYPE_VARCHAR , TYPE_NUMERIC |
Serial | TYPE_SERIAL , TYPE_BIGSERIAL , TYPE_SMALLSERIAL |
Temporal | TYPE_DATE , TYPE_TIME , TYPE_INTERVAL |
Binary | TYPE_BYTEA |
Network | TYPE_INET , TYPE_CIDR , TYPE_MACADDR |
Geometric | TYPE_POINT , TYPE_LINE , TYPE_POLYGON , etc. |
Full Text | TYPE_TSVECTOR , TYPE_TSQUERY |
Many types support additional configuration through type-specific options:
message Column {
string email = 1 [(postgres_proto_schema.v1.column_options) = {
type: TYPE_VARCHAR
varchar: {
length: 255
collation: "en_US"
}
}];
}
Tables support comprehensive PostgreSQL configuration:
message MyTable {
option (.postgres_proto_schema.v1.table_options) = {
table_name: "my_table"
schema: "public"
tablespace: "fast_disk"
is_unlogged: false
is_temporary: false
// Storage parameters
storage_parameters: {
key: "fillfactor"
value: "70"
}
// Indexes
indexes: [{
name: "my_index"
columns: ["column1", "column2"]
index_method: INDEX_METHOD_BTREE
unique: true
where_clause: "deleted_at IS NULL"
}]
// Row Level Security
rls_policies: [{
name: "tenant_isolation"
using_expression: "tenant_id = current_tenant_id()"
with_check_expression: "tenant_id = current_tenant_id()"
role: "authenticated"
}]
// Partitioning
partitioning: {
method: PARTITION_METHOD_RANGE
keys: ["created_at"]
}
};
}
Different column types support specific configuration options:
message TypeExamples {
// VARCHAR with collation
string text = 1 [(postgres_proto_schema.v1.column_options) = {
type: TYPE_VARCHAR
varchar: {
length: 255
collation: "en_US"
}
}];
// NUMERIC with precision
double amount = 2 [(postgres_proto_schema.v1.column_options) = {
type: TYPE_NUMERIC
numeric: {
precision: 10
scale: 2
}
}];
// TIMESTAMP with timezone
string created_at = 3 [(postgres_proto_schema.v1.column_options) = {
type: TYPE_TIMESTAMPTZ
time: {
precision: 6
}
}];
}
Available constraint types:
CONSTRAINT_TYPE_PRIMARY_KEY
CONSTRAINT_TYPE_NOT_NULL
CONSTRAINT_TYPE_UNIQUE
CONSTRAINT_TYPE_CHECK
CONSTRAINT_TYPE_FOREIGN_KEY
CONSTRAINT_TYPE_EXCLUSION
Example:
message Order {
int32 id = 1 [(postgres_proto_schema.v1.column_options) = {
constraints: [{
type: CONSTRAINT_TYPE_PRIMARY_KEY
}]
}];
int32 user_id = 2 [(postgres_proto_schema.v1.column_options) = {
constraints: [{
type: CONSTRAINT_TYPE_FOREIGN_KEY
foreign_key: {
foreign_table: "users"
foreign_column: "id"
}
}]
}];
}
You can mark messages as PostgreSQL composite types:
message Address {
option (.postgres_proto_schema.v1.is_composite_type) = true;
string street = 1 [(postgres_proto_schema.v1.column_options) = {
type: TYPE_VARCHAR
varchar: { length: 255 }
}];
string city = 2 [(postgres_proto_schema.v1.column_options) = {
type: TYPE_VARCHAR
varchar: { length: 100 }
}];
}
The package provides two built-in patterns for common PostgreSQL table requirements:
Automatically adds created_at, updated_at, and deleted_at columns:
message User {
option (.postgres_proto_schema.v1.timestamps) = {
track_created: true
track_updated: true
track_deleted: true
};
}
Tracks record creators and updaters:
message User {
option (.postgres_proto_schema.v1.audit) = {
track_creator: true
track_updater: true
audit_schema: "audit"
};
}
The package includes built-in support for major PostgreSQL platforms through the Platform
enum:
Category | Platforms |
---|---|
Cloud | PLATFORM_RDS , PLATFORM_AURORA , PLATFORM_CLOUD_SQL , PLATFORM_AZURE |
Managed | PLATFORM_HEROKU , PLATFORM_DIGITALOCEAN , PLATFORM_SUPABASE |
Enterprise | PLATFORM_ENTERPRISEDB , PLATFORM_TIMESCALEDB , PLATFORM_CRUNCHY |
Versions | PLATFORM_15 , PLATFORM_16 , PLATFORM_17 |
This package includes both compile-time and runtime validation through protovalidate:
message User {
string email = 1 [(buf.validate.field).string.email = true];
int32 age = 2 [(buf.validate.field).int32 = {
gte: 0
lte: 120
}];
}
For runtime validation in Go:
import "github.com/bufbuild/protovalidate-go"
validator, err := protovalidate.New()
if err != nil {
log.Fatal(err)
}
if err := validator.Validate(msg); err != nil {
log.Printf("validation failed: %v", err)
}
See the protovalidate documentation for more validation options and language-specific usage.
// Simple table with basic columns
message User {
option (.postgres_proto_schema.v1.table_options) = {
table_name: "users"
schema: "public"
};
int32 id = 1 [(postgres_proto_schema.v1.column_options) = {
type: TYPE_SERIAL
constraints: [{ type: CONSTRAINT_TYPE_PRIMARY_KEY }]
}];
string email = 2 [(postgres_proto_schema.v1.column_options) = {
type: TYPE_VARCHAR
varchar: { length: 255 }
constraints: [{ type: CONSTRAINT_TYPE_UNIQUE }]
}];
}
// Multi-tenant table with RLS and timestamps
message TenantResource {
option (.postgres_proto_schema.v1.table_options) = {
table_name: "tenant_resources"
schema: "public"
indexes: [{
name: "tenant_resources_tenant_id_idx"
columns: ["tenant_id"]
}]
rls_policies: [{
name: "tenant_isolation"
using_expression: "tenant_id = current_tenant_id()"
}]
};
option (.postgres_proto_schema.v1.timestamps) = {
track_created: true
track_updated: true
};
string tenant_id = 1 [(postgres_proto_schema.v1.column_options) = {
type: TYPE_UUID
constraints: [{ type: CONSTRAINT_TYPE_NOT_NULL }]
}];
}
// Complex table with multiple features
message Product {
option (.postgres_proto_schema.v1.table_options) = {
table_name: "products"
schema: "inventory"
partitioning: {
method: PARTITION_METHOD_RANGE
keys: ["created_at"]
}
indexes: [{
name: "products_search_idx"
columns: ["name", "description"]
index_method: INDEX_METHOD_GIN
expression: "to_tsvector('english', name || ' ' || description)"
}]
};
option (.postgres_proto_schema.v1.timestamps) = {
track_created: true
track_updated: true
track_deleted: true
};
option (.postgres_proto_schema.v1.audit) = {
track_creator: true
track_updater: true
};
// ... columns
}
postgres_proto_schema/
├── proto/
│ └── postgres_proto_schema/
│ └── v1/
│ ├── schema.proto # Core schema definitions and extensions
│ ├── table.proto # Table-specific options and types
│ ├── column.proto # Column-specific options and types
│ └── common.proto # Shared types and enums
├── gen/ # Generated code directory
│ ├── ts/ # TypeScript generated code
│ └── go/ # Go generated code
├── buf.yaml # Buf module definition
└── buf.gen.yaml # Code generation configuration
- Lint the Protobuf files:
buf lint
- Build and validate the module:
buf build
- Push the module to the Buf Schema Registry:
buf push
Contributions are welcome! To contribute:
- Fork the repository.
- Create a feature branch.
- Submit a pull request with a detailed description of your changes.
This project is licensed under the MIT License. See LICENSE
for details.
- PostgreSQL: 12+
- Protocol Buffers: 3
- Go: 1.21+
- TypeScript: 4.5+
For questions, suggestions, or support, open an issue on the GitHub repository.