ysaqml provides a YAML-backed persistence layer for SQLAlchemy.
Project description
ysaqml
Overview
ysaqml provides a YAML-backed persistence layer for SQLAlchemy. Tables live in
memory inside SQLite for fast queries, while their contents are loaded from –
and saved back to – .yaml files using the blazing-fast naay
parser/dumper.
Why?
- Keep relational workflows while still committing plain-text fixtures.
- Edit data in YAML, rely on SQLite for constraints and transactions.
- Round-trip friendly thanks to naay's strict string-only subset.
Installation
pip install -e .
This pulls in SQLAlchemy and naay. Tests rely on pytest (install with
pip install -e .[test]).
Usage
Context-managed workflow
from pathlib import Path
from sqlalchemy import Column, Integer, MetaData, String, Table, select
from ysaqml import YamlSqliteEngine
metadata = MetaData()
users = Table(
"users",
metadata,
Column("id", Integer, primary_key=True),
Column("name", String, nullable=False),
)
data_dir = Path("./data")
with YamlSqliteEngine(metadata, data_dir) as backend:
engine = backend.engine
with engine.begin() as conn:
conn.execute(users.insert().values(id=1, name="Ada"))
result = conn.execute(select(users)).mappings().all()
print(result)
# context manager flushes SQLite rows back into data/users.yaml
Each SQLAlchemy table is materialized to <data_dir>/<table_name>.yaml. When
entering the context the engine wipes any existing rows in the in-memory
database, rehydrates them from YAML if the file exists, and on successful
exit dumps the SQLite contents back to YAML.
Custom dialect / engine helper
ysaqml also registers a SQLAlchemy dialect so you can build engines with
ysaqml:/// URLs. The convenience helper wires up the required engine plugin
and disposes the engine when you are done:
from contextlib import closing
from pathlib import Path
from sqlalchemy import Column, Integer, MetaData, String, Table, select
from ysaqml import create_yaml_engine
metadata = MetaData()
users = Table(
"users",
metadata,
Column("id", Integer, primary_key=True),
Column("name", String, nullable=False),
)
data_dir = Path("./data")
with closing(create_yaml_engine(metadata, data_dir)) as engine:
with engine.begin() as conn:
conn.execute(users.insert().values(id=1, name="Ada"))
print(conn.execute(select(users)).mappings().all())
# exiting the context disposes the engine and writes YAML files
Under the hood this builds an in-memory SQLite engine using the ysaqml dialect
and attaches an engine plugin that loads YAML files immediately and saves them
back when the engine is disposed. If you manage the engine manually, make sure
to call engine.dispose() to persist your changes.
File format
Every YAML document uses the following schema:
_naay_version: "1.0"
rows:
- id: "1"
name: "Ada"
_naay_versionis validated but not enforced – it defaults toysaqml.DEFAULT_NAAY_VERSIONand is kept intact when re-saving.rowsis an ordered list of dictionaries where every value is a string.
ysaqml serializes Python None values as the sentinel string __NULL__. When
loading back, that string becomes None again, so avoid storing it as a
literal value.
Testing
pytest
The tests create temporary directories and exercise the full load → mutate → dump loop.
License
Released under the GNU LGPL-3.0-or-later.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ysaqml-2025.12.6.post4.tar.gz.
File metadata
- Download URL: ysaqml-2025.12.6.post4.tar.gz
- Upload date:
- Size: 31.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
686f66fd54743eed50eee08752e4b1b698ecc372947d7fea874e710a703ab1d7
|
|
| MD5 |
be330b393fcb06a41e92656b6bd9b7b6
|
|
| BLAKE2b-256 |
c0b713237d383be66913e9a42d0abdd2e872f3712f11c51f51563912e85de0fe
|
Provenance
The following attestation bundles were made for ysaqml-2025.12.6.post4.tar.gz:
Publisher:
release.yml on rbroderi/ysaqml
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ysaqml-2025.12.6.post4.tar.gz -
Subject digest:
686f66fd54743eed50eee08752e4b1b698ecc372947d7fea874e710a703ab1d7 - Sigstore transparency entry: 747237324
- Sigstore integration time:
-
Permalink:
rbroderi/ysaqml@bd9c6e119a27d6d8000d4aa4f9d5f6f3efc9a314 -
Branch / Tag:
refs/tags/2025.12.06-4 - Owner: https://github.com/rbroderi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@bd9c6e119a27d6d8000d4aa4f9d5f6f3efc9a314 -
Trigger Event:
release
-
Statement type:
File details
Details for the file ysaqml-2025.12.6.post4-py3-none-any.whl.
File metadata
- Download URL: ysaqml-2025.12.6.post4-py3-none-any.whl
- Upload date:
- Size: 13.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1aee12303d7e5e9e4af1ed4bd75980b65042172be36fa5d33b7bcda3abd7c85e
|
|
| MD5 |
c6a12e4f9c2b4ee7b7e536b1086048a9
|
|
| BLAKE2b-256 |
bfd400c371bfdf85cef3cd53edc8cea79a33a795c44fabde7ce4b6250aec93e3
|
Provenance
The following attestation bundles were made for ysaqml-2025.12.6.post4-py3-none-any.whl:
Publisher:
release.yml on rbroderi/ysaqml
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ysaqml-2025.12.6.post4-py3-none-any.whl -
Subject digest:
1aee12303d7e5e9e4af1ed4bd75980b65042172be36fa5d33b7bcda3abd7c85e - Sigstore transparency entry: 747237326
- Sigstore integration time:
-
Permalink:
rbroderi/ysaqml@bd9c6e119a27d6d8000d4aa4f9d5f6f3efc9a314 -
Branch / Tag:
refs/tags/2025.12.06-4 - Owner: https://github.com/rbroderi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@bd9c6e119a27d6d8000d4aa4f9d5f6f3efc9a314 -
Trigger Event:
release
-
Statement type: