stokoe/statamic-postgres-engine

There is no license information available for the latest version (dev-main) of this package.

Maintainers

Package info

github.com/Stokoe-dev/statamic-postgres-engine

pkg:composer/stokoe/statamic-postgres-engine

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

dev-main 2026-05-07 07:52 UTC

This package is auto-updated.

Last update: 2026-05-07 07:54:33 UTC


README

Important notice: This addon is in an alpha state. Expect bugs. Do not use in production without rigorous testing. Please raise issues.

A PostgreSQL-native content engine for Statamic 6. Replaces flat-file Stache storage with PostgreSQL while preserving full compatibility with Statamic's Query Builder, GraphQL API, Antlers tags, and Control Panel.

No Eloquent models. No statamic/eloquent-driver. Direct PostgreSQL storage through Statamic's repository contracts.

What it does

  • Stores all Statamic content types in PostgreSQL: collections, entries, taxonomies, terms, globals, navigations, asset containers, forms, submissions, and revisions
  • Uses PostgreSQL-native features: JSONB for flexible data, UUID primary keys, citext for case-insensitive handles, tsvector for full-text search, pg_trgm for fuzzy search
  • Provides bidirectional import/export between flat files and PostgreSQL
  • Includes observability tooling: slow query logging, query profiling, health checks

What it doesn't do

  • Does not use Eloquent models for content persistence
  • Does not require statamic/eloquent-driver
  • Does not introduce a custom query API — everything works through standard Statamic methods
  • Does not store blueprints, fieldsets, or users — those stay in their default locations

Requirements

  • PHP 8.5+
  • PostgreSQL 15+
  • Statamic 6
  • Laravel 13

Installation

1. Install the package

composer require stokoe/postgres-engine

2. Configure your database

Your .env should have a PostgreSQL connection:

DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=your_database
DB_USERNAME=your_user
DB_PASSWORD=your_password

3. Activate the addon

Add this to your .env:

POSTGRES_ENGINE_CONNECTION=pgsql

Without this line, the addon stays dormant and Statamic uses Stache as normal.

4. Run migrations

php artisan migrate

5. Verify

php artisan pg-engine:doctor

All checks should pass.

6. Publish config (optional)

php artisan vendor:publish --tag=postgres-engine-config

See INSTALL.md for the full installation guide including troubleshooting.

Usage

Once activated, the addon is transparent. All standard Statamic code works without modification:

// Query Builder — works identically
Entry::query()->where('collection', 'blog')->orderBy('date', 'desc')->get();

// Facades — work identically
Collection::findByHandle('blog');
Taxonomy::findByHandle('tags');
GlobalSet::findByHandle('site_settings');

// Repository contracts — resolve to PostgreSQL implementations
app(EntryRepository::class)->find($id);
app(CollectionRepository::class)->all();

Antlers templates, GraphQL queries, and the Control Panel all work without changes.

Import & Export

Import flat files into PostgreSQL

# Dry-run first (validates without writing)
php artisan pg-engine:import content --dry-run

# Full import
php artisan pg-engine:import content

Export PostgreSQL back to flat files

php artisan pg-engine:export storage/app/export --overwrite

Import specific content types

php artisan pg-engine:import content --type=collections
php artisan pg-engine:import content --type=entries --collection=blog
php artisan pg-engine:import content --type=taxonomies
php artisan pg-engine:import content --type=terms --taxonomy=tags
php artisan pg-engine:import content --type=globals
php artisan pg-engine:import content --type=navigations
php artisan pg-engine:import content --type=assets
php artisan pg-engine:import content --type=forms
php artisan pg-engine:import content --type=submissions
php artisan pg-engine:import content --type=revisions

Export specific content types

php artisan pg-engine:export path/to/export --type=collections --overwrite
php artisan pg-engine:export path/to/export --type=globals --overwrite
php artisan pg-engine:export path/to/export --type=navigations --overwrite

Import is idempotent — running it twice updates existing records without creating duplicates. Export supports --dry-run and --overwrite flags. Sensitive metadata (IP hashes, user agent hashes) is excluded from exports.

See docs/IMPORT_EXPORT.md for the full import/export architecture.

Switching Between PostgreSQL and Flat Files

Mode .env setting Content source
PostgreSQL POSTGRES_ENGINE_CONNECTION=pgsql pg_* tables
Flat files Line removed or commented content/ YAML/MD files

To switch back to flat files:

# Comment out the activation line in .env
# POSTGRES_ENGINE_CONNECTION=pgsql

# Clear caches
php artisan cache:clear
php artisan statamic:stache:clear
php artisan statamic:stache:warm

To switch back to PostgreSQL, uncomment the line. No reimport needed.

Commands

Command Description
pg-engine:doctor Health check: connection, extensions, tables, indexes, bindings
pg-engine:import {path} Import flat files into PostgreSQL
pg-engine:export {path} Export PostgreSQL content to flat files
pg-engine:reindex Rebuild full-text search indexes
pg-engine:search:test {query} Test search queries interactively
pg-engine:stats Query statistics and slow query report

All commands support --help for full option details.

Search

The addon provides PostgreSQL-native search with four modes:

  • Full-text search — tsvector-based, language-aware, ranked by relevance
  • Fuzzy search — pg_trgm trigram matching for typo tolerance
  • Hybrid search — combines full-text and fuzzy results
  • Accent-insensitive search — uses the unaccent extension

Search weights are configurable per field (A/B/C/D ranking). Rebuild indexes after import:

php artisan pg-engine:reindex

Architecture

See docs/ARCHITECTURE.md for the full technical architecture.

The addon is structured in layers:

ServiceProvider          — Registers all bindings, validates config
  ├── Repositories       — Implement Statamic contracts (Entry, Collection, etc.)
  │     ├── Hydrators    — Convert DB rows ↔ Statamic objects
  │     └── Storage      — Raw PostgreSQL operations (no Eloquent)
  ├── Query              — EntryQueryBuilder, TermQueryBuilder, SQL compilation
  ├── Search             — Full-text, fuzzy, hybrid search engine
  ├── Import/Export      — Bidirectional flat-file ↔ PostgreSQL
  ├── Observability      — Query profiling, slow query logging
  ├── Support            — Identity map, cycle detector, bulk loader
  └── Commands           — Artisan commands (doctor, import, export, reindex, stats)

Testing

composer test

The test suite enforces strict guards — any incomplete, skipped, or noticed test fails the run:

  • 976 tests, 5114 assertions
  • 0 incomplete, 0 skipped, 0 PHPUnit notices
  • failOnIncomplete, failOnSkipped, failOnNotice, failOnRisky all enabled

Compatibility

This addon maintains full compatibility with:

  • Statamic Query BuilderEntry::query(), where(), orderBy(), paginate(), JSONB dot-notation
  • Statamic GraphQL API — collections, entries, globals, filtering, sorting, pagination
  • Antlers tags{{ collection }}, {{ nav }}, {{ global }}, all standard tags
  • Control Panel — listings, filtering, sorting, pagination, publish/unpublish
  • Native Statamic objectsEntry, Collection, Term, GlobalSet, Nav, etc.

Existing Statamic code works without modification.

Postgres Engine is a Commercial Addon.

You can use it for free while in development, but requires a license to use on a live site. Learn more or buy a license on The Statamic Marketplace!