Skip to content

Storage Backends

pH7x Systems edited this page Jul 18, 2026 · 4 revisions

Storage Backends

Storage is a strict contract (cms_core.storage.StorageBackend) with versioned, shared ANSI migrations. The database is never the portable source of truth — JSON/Markdown export is.

Supported engines

Engine URL Notes
SQLite (default) sqlite:///content.sqlite3 Development and small sites; WAL mode + busy timeout
PostgreSQL postgresql://user:pass@host:5432/db Production; pip install "cms-core[postgres]" (psycopg 3)

SQL Server and MySQL/MariaDB are planned in the same mold (own ADR each, optional extra, shared migrations).

Usage

from cms_core import create_storage

with create_storage("sqlite:///content.sqlite3") as storage:
    storage.migrate()                 # apply pending schema migrations
    print(storage.schema_version())   # current version
    articles = storage.load_all_articles()

The factory (create_storage(url)) resolves the engine from the URL scheme — every caller (CLI, admin, your code) works unchanged across engines.

Contract surface

Articles, pages and media assets: save_* / load_* / delete_* / list_*_ids / load_all_*. Admin accounts and sessions: save_user / load_user / delete_user / list_usernames, save_session / load_session / delete_session / delete_expired_sessions. Accounts live in the database via the shared migrations but are never exported.

Migrations

Numbered, shared across engines, tracked per engine (SQLite user_version, PostgreSQL a version table). storage.migrate() is idempotent; the admin's /healthz reports the migrated schema version.

Conformance suite

Every engine runs the same test suite. SQLite always runs; PostgreSQL runs when STILLSITE_POSTGRES_URL is set (CI uses a service container; locally, any PostgreSQL instance works — the suite wipes the public schema). Never silently faked: unset URL means skipped, visibly.

Clone this wiki locally