The reference Python implementation of the OpenStatSpec specification.
This package implements the specification; it does not define or extend it.
The normative model lives in the OpenStatSpec/specification repository.
Python 0.9.0 pins released specification v0.5.0 at
864e84479f554b8ee250ffed44c4dfb963750d4a and selects SAV/ZSAV 1.0 with
database_io_policy=openstatspec-database-io-v1. It implements the explicitly
selected optional official SPSS Frontend 0.3 over unchanged Plan 0.1/0.2, not
the separate optional Transformation Workflow 0.3 profile.
For each supported import, one source dataset becomes one dedicated wide SQL
table. Cases are rows and source variables are physical SQL columns. The
singular UUID-keyed tables from the specification (dataset, variable,
operation, fidelity_event, and related metadata tables) are the public
catalog contract and the only catalog representation created or read by the
adapter. Databases created with the former *_catalog compatibility schema
must be remediated to the normative schema before use. The adapter does not
reshape data, create EAV or long-form tables, or harmonize studies or waves.
Unsupported source features, SQL targets, or export paths fail explicitly. There is no silent truncation, type conversion, metadata loss, or partial import.
openstatspec.core: pure standard concepts, validation, versions, capabilities, and loss reports.openstatspec.sql: database connection and wide-table/catalog operations.openstatspec.spss: SAV/ZSAV adapter boundary.openstatspec.transform: canonical plans, frontend-neutral schema concepts, and plan validation.openstatspec.frontends.spss: the SPSS-like syntax frontend and convenience execution adapter.
from openstatspec import export_sav, import_sav
import_sav("responses.sav", database_url="postgresql+psycopg://user:password@server/database", dataset_id="responses-2026")
export_sav(database_url="postgresql+psycopg://user:password@server/database", dataset_id="responses-2026", destination="responses-roundtrip.sav")openstatspec import responses.sav --database-url postgresql+psycopg://... --dataset-id responses-2026
openstatspec export --database-url postgresql+psycopg://... --dataset-id responses-2026 --output responses-roundtrip.sav
Imported datasets remain immutable source records. The optional SQL
transformation profile can register versioned, parameterized SQLite SELECT queries,
materialize results, record lineage and weights, and expose
derived datasets through a public catalog API. It uses a separate profile
catalog and never presents SQL output as an imported source dataset.
Workflow operations support SQLite only in this milestone and fail closed on
PostgreSQL/MySQL/MariaDB; core import/export database support is unchanged.
The core SQLite import/export profile accepts SQLite >=3.24.0,<4.0.0; the
optional transformation workflow deliberately has the narrower
>=3.35.0,<4.0.0 runtime preflight. These independent tiers do not change the
server-profile matrix. Microsoft SQL Server is not supported; its future
dialect is scoped only in the specification's
MSSQL roadmap.
See the SQL transformation workflow for Python and CLI examples, migration behavior, hashing, atomicity, and the exact implemented capability boundary.
The bounded SPSS-like frontend lowers RECODE, sequential COMPUTE and IF,
STRING declarations, and DELETE VARIABLES,
VARIABLE LABELS, VALUE LABELS, numeric FORMATS, VARIABLE LEVEL, and
EXECUTE into a language-neutral typed canonical plan. Conditions support
parentheses, variable and numeric literal operands, comparisons, AND, and
OR. String comparison and v0.2 string assignment currently fail closed.
The in-place path applies the plan to the same logical dataset, physical wide
table, and normative/compatibility metadata without a derived dataset, copied
table, snapshot, or hidden history layer. Numeric targets may be created
atomically on SQLite and PostgreSQL. MySQL, MariaDB, and Dolt fail closed on
target_mode=create and require a separately provisioned physical and catalog
target before assignment. Dolt requires the caller's exact clean branch/HEAD,
leaves success as an inspectable working-set diff, and never calls
DOLT_COMMIT.
Explicitly select official Frontend 0.3 with compile_spss_request, or pass
frontend_contract="openstatspec-spss-syntax-frontend-v0.3" to the typed compiler
or in-place API. Default APIs and the CLI retain their compatibility behavior;
STRING and DELETE VARIABLES remain Python extensions, not official 0.3.
New schema-changing output uses Python-owned IDs that older readers cannot load.
Upgrade consumers first; legacy plans retain their canonical JSON and hashes,
and stored audits are not migrated. Recompiling schema-changing syntax changes
its plan hash. See compatibility and migration.
See the dataset transformations manual for schema installation, Python and CLI surfaces, database invariants, audit provenance, package layout, and extension guidance. Stata and SAS are unimplemented placeholders.
The adapter requires openstatspec-pyspssio==0.5.1.post2 as its sole SPSS
engine. Its import module remains pyspssio; the exact source commit is recorded
in operation metadata. There is no fallback reader or writer. It supports unencrypted SAV and ZSAV import and
SAV/ZSAV export for the semantics exposed by that engine. SQLite is the local
reference path.
PostgreSQL, MySQL, MariaDB, and Dolt are each covered by separate service-backed CI
conformance checks. Dolt support is an independent core profile for the
exact write-supported versions 2.2.2 and 2.2.3; all other versions (including
2.3.0), noncanonical versions, and unknown MySQL-wire products fail closed for writes.
The supported family claims are broader than the deliberately exact CI
evidence points: PostgreSQL 17.x/18.x is exercised at 17.10/18.4, MySQL
8.4.x/9.7.x at 8.4.11/9.7.2, and MariaDB 11.4.x/11.8.x/12.3.x at
11.4.12/11.8.8/12.3.2. Each service job checks the normalized live server
version against its exact matrix entry before that run can count as evidence.
Dolt's default-write service checks run independently at exact versions 2.2.2
and 2.2.3 using immutable container-image digests. Release/CI owns this evidence;
normal callers need no declaration or evidence files. The optional explicit
DoltConformanceSource override remains strict and does not fall back to the
default policy if its declarations are missing, invalid, or mismatched.
| Engine/profile | Runtime supported policy | Exact CI-tested versions |
|---|---|---|
| SQLite core / optional workflow | Core >=3.24.0,<4.0.0; optional workflow >=3.35.0,<4.0.0 |
Runtime-provided SQLite on Python 3.11–3.14 runners; not a pinned server image |
| PostgreSQL | 17.x and 18.x | 17.10 and 18.4 |
| MySQL | 8.4.x and 9.7.x | 8.4.11 and 9.7.2 |
| MariaDB | 11.4.x, 11.8.x, and 12.3.x | 11.4.12, 11.8.8, and 12.3.2 |
| Dolt writes | Exactly 2.2.2 and 2.2.3 | 2.2.2 and 2.2.3 |
Microsoft SQL Server (MSSQL) remains roadmap-only and is not a supported runtime profile; see the specification's MSSQL roadmap.
Use these explicit SQLAlchemy URLs:
- SQLite:
sqlite:///dataset.sqlite - PostgreSQL:
postgresql+psycopg://user:password@host/database - MySQL/MariaDB:
mysql+pymysql://user:password@host/database - Dolt 2.2.2 or 2.2.3:
mysql+pymysql://user:password@host/database(detected by server identity)
The Dolt core profile supports strict wide-table import, validation, and export; the separate Transformation Workflow is unsupported.
Run openstatspec capabilities before an integration to inspect the
machine-readable feature matrix. Export is deliberately strict: if known
dictionary semantics cannot be reproduced, it stops until you pass the exact
diagnostic code with --allow-loss. Diagnostics are returned to the caller, not
persisted. Reads, validation, and SAV/ZSAV export never write to the database,
including on failure. Export returns no operation_id and needs only read
permissions; Dolt reads have no write-version or write-variable-count gate.
Read operations reject missing SQLite files without creating them. Imports and transformations
use the packaged exact-version policy by default. Active driver/identity checks,
limit preflight, and the clean expected branch/HEAD guard for in-place apply
remain mandatory. Dolt's reported limits are adapter safety budgets, narrowed
by the active packet limit, not proven native server ceilings; full boundary
conformance is not claimed.
The matrix is also available to Python callers as
openstatspec.capability_matrix(). It distinguishes supported semantics from
unobservable and fail-closed paths; see the SAV profile for the exact
the openstatspec-pyspssio boundary.
See the SAV profile for feature boundaries and release readiness for the pre-tag checklist. Read third-party notices before distributing a bundled application: the required engine includes IBM redistributables under separate terms.