Repository navigation
Releases: vsdudakov/yara-orm
Release list
1.19.1 — decimal precision
Decimal precision fix: a Decimal with more than 28 decimal places, such as 1 / Decimal("162.35"), now binds instead of failing with invalid decimal "…": Failed to parse, and DecimalField rounds to its decimal_places before binding, as Tortoise did. Highlights:
Fixed
- Decimals with more than 28 decimal places bind instead of failing. The engine's
rust_decimalholds at most 28 places, even though NUMERIC accepts any scale. The binder now rounds the extra fractional digits half away from zero, as PostgreSQL does. Values that fit still bind exactly. A value whose integer part is too large, NaN or infinity still raises, and the error now gives the limit. (#31) DecimalFieldrounds todecimal_placesbefore binding, half away from zero, so model writes store the column's scale on every backend, including SQLite, which has no column scale of its own. (#31)
Behaviour note: decimal values passed for a DecimalField, filter values included, are now rounded to the field's scale. On SQLite the stored text carries the full scale (1.5 is written as 1.5000000000); the value compares equal.
Full details in CHANGELOG.md.
1.19.0 — password provider
Password provider release: a PostgreSQL pool can now call a function for its password each time it opens a connection, so short-lived credentials such as RDS IAM tokens are created at connect time instead of being refreshed on a timer. Highlights:
Added
YaraOrm.set_passwordaccepts a callable. The PostgreSQL pool calls it each time it opens a new connection and uses the string it returns, so an expiring credential such as an RDS IAM token is created at connect time instead of being refreshed on a timer. The callable runs on a worker thread, so a slow token fetch does not stall queries on connections already open. A plain string still works as before. Any other type raisesTypeError. (#29, thanks @senhadjielrhazi)
Changed
- Dev tooling moves into
pyproject.tomldependency groups.ruffandtyare pinned in alintgroup (ruff==0.17.0,ty==0.0.86); build and test tools are in atestgroup;devincludes both. CI andmake devinstall them withpip install --group …, so a newtyrelease can no longer fail lint on unrelated pull requests. (#30) - Build and docs minimums raised to
maturin>=1.15.0andmkdocs-material>=9.7.7.
Full details in CHANGELOG.md.
1.18.0 — password rotation
Password rotation release: a PostgreSQL pool can now take a new password without being rebuilt, so short-lived credentials such as RDS IAM tokens refresh without failing in-flight queries. Highlights:
Added
YaraOrm.set_password(password, connection="default")rotates a PostgreSQL pool's password in place. PostgreSQL checks the password only when a connection opens, so the next connection the pool opens presents the new one; the pool stays open and connections already in use keep working. Refresh an RDS IAM authentication token (15 minutes) on a shorter timer instead of opening a second pool and closing the one serving traffic, which failed in-flight queries withPool has been closed. Until the first rotation the URL's password is used exactly as parsed. Other backends raiseValueError. (#28, thanks @senhadjielrhazi)
Changed
- PostgreSQL connection errors carry the server's message and SQLSTATE. A failed connect used to surface as the driver's bare
db error; it now reads e.g.password authentication failed for user "app" (SQLSTATE 28P01). Code that matched on the olddb errortext needs updating.
Full details in CHANGELOG.md.
1.17.0 — PostgreSQL sslmode follows libpq
PostgreSQL TLS release: sslmode now follows libpq, so managed databases with a private CA (RDS/Aurora, Cloud SQL, Azure) connect under the default mode again. Highlights:
Fixed
- PostgreSQL
sslmodenow follows libpq. Every mode exceptdisableverified the server certificate against the OS trust store, soprefer(the default, and the mode most URLs inherit without saying so) could not reach a managed database at all: RDS/Aurora, Cloud SQL and Azure present a certificate signed by their own private CA, and the handshake failed withUnknownIssuerbefore the first query. As in libpq (and therefore asyncpg and psycopg),preferandrequirenow encrypt without authenticating the server. The connection is still TLS; this is not a fallback to plaintext.
Added
sslmode=verify-caandsslmode=verify-fullare accepted in PostgreSQL URLs and are the way to ask for certificate verification now thatrequireno longer implies it.verify-cachecks the chain,verify-fullalso checks the hostname.sslrootcert=<path>adds the PEM roots in that file to the trust store for the verifying modes (typically the RDS/Cloud SQL CA bundle). As in libpq, it does not by itself turn verification on. An unreadable file, or one holding no certificate, is a configuration error rather than a silent fallback to the OS roots.
Full details in CHANGELOG.md.
1.16.0 — construction semantics
Construction semantics release: an instance now agrees with the row it writes in four places that previously needed application-side shims, plus a bulk_update batching fix. Highlights:
Added
Model.__iter__: instances iterate as(name, value)pairs, sodict(instance)works and pair-walking consumers (pydanticfrom_attributes, serializers, factories) take a model directly. Declared columns first in declaration order, columns absent underonly()/defer()skipped rather than fetched, private attributes omitted,Meta.extra_kwargs = "store"extras last.
Changed
- An explicit
<name>_idwins over a relation object at construction.Book(author=obj, author_id=x)used to storeobj.pk; it now keepsx(by field name or db-column alias), and an object whose pk disagrees is not cached as the prefetched relation. Factories need this: aSubFactoryis evaluated even when the caller passesauthor_id=. Passing only one form is unchanged. auto_now_addfills the column instead of imposing a value. Backdated fixtures, imports and backfills keep the stamp they pass.auto_nowstill always stamps, as does a field declaring both.
Fixed
- Foreign-key columns are coerced on assignment.
create(parent_id=str(pk))left the rawstron the instance, sochild.parent_id == parent.idwasFalseuntil re-fetch.ForeignKeyFieldInstance.to_python_valuenow mirrorsto_dband the<name>_idcolumn is normalised in__init__like every other coerced column. bulk_updaterespects the dialect's bind-parameter ceiling. Batches are clamped frommax_bind_params(each row costs a(pk, value)pair per field plus a pk slot inWHERE ... IN), so a largebatch_sizeno longer overflows PostgreSQL's 65535 / SQL Server's 2100 limit; SQLite now declares its default 32766.
Full details in CHANGELOG.md.
1.15.0 — custom PostgreSQL column types
Feature release: custom PostgreSQL column types (pgvector vector, inet, citext, ...) now work end-to-end through the ORM. Highlights:
Added
yara_orm.RawText: a thinstrsubclass that binds as an untyped text parameter on PostgreSQL — the server infers the type from context (target column,<=>operand) and parses the text through the type's own input function. Custom field kinds return it fromto_db; previously every ORM INSERT/UPDATE into such a column failed with SQLSTATE 42804 unless the database installed a globalCREATE CAST (text AS ...) WITH INOUT AS IMPLICIT. On every other backend it binds like a plain string.Field.select_as_text: PostgreSQL SELECT/RETURNING projections read the column throughCAST(col AS text)andto_pythonparses the text form — previously selecting a custom-typed column raisedunsupported PostgreSQL type OID, forcing.defer()workarounds. Applied at every projection site (full-row,only()/defer(),select_related,values(), m2m prefetch, RETURNING) via the newBaseDialect.select_columnhook; comparisons and grouping keep the column's real type.- The custom-fields guide documents both on a complete pgvector
VectorFieldexample.
Full details in CHANGELOG.md.
1.14.5 — create-path type coercion
Correctness fix release. Highlights:
Fixed
- Create paths return canonical Python types:
create(),get_or_create(),update_or_create(),bulk_create()and their QuerySet variants previously kept loose input (a string for a decimal or UUID column) as a rawstron the returned instance, whileget()yieldedDecimal/UUID.DecimalField,UUIDField,BooleanField(semantic string handling —bool("false")would beTrue),TimeDeltaField,IntEnumFieldandCharEnumFieldnow normalise on assignment, socreate(balance="12.34").balanceis aDecimaland matches a fetched row. update_from_dict(theupdate_or_createupdate path) applies the same coercion.JSONFieldis deliberately unchanged (a string is a valid JSON value); int/float/char fields stay identity to keep the plain construction fast path.
Full details in CHANGELOG.md.
1.14.4 — correctness hotfix
Correctness hotfix release. Highlights:
Changed
ManyToManyField(through_fields=...)now reads Django's(owner_column, target_column)order — declarations written against the previous(forward_key, backward_key)reading must swap the two elements (the explicitforward_key=/backward_key=kwargs are unchanged).- Related-manager bulk writes are unscoped:
parent.children.update(...)/.delete()reach every related row even under a soft-deleteMeta.manager; reads keep the manager scope.
Fixed
- Oracle: zero-fraction datetime binds compared unequal to stored values, so
col >= :midnightdropped exact-midnight rows — such values now bind as DATE. - Datetime write paths:
DatetimeField.to_dbwidens bare dates to midnight datetimes (plain-attributesave(),update(),bulk_update()no longer store date-only text); the__datelookup narrows its value to a date. - m2m cleanup is atomic on non-cascading dialects (SQL Server): a failed row delete no longer strips the surviving rows' join links.
- SQL Server
bulk_create: ids return viaOUTPUT ... INTO(works with triggers, error 334 gone) in arrival order (correct under negative IDENTITY increments). bulk_get_or_create/bulk_update_or_createaccept a mix of explicit and auto pks.- PostgreSQL
execute_many: numeric mixes widen to NUMERIC (no precision loss above 2^53); naive/aware datetime and str/UUID mixes are accepted. - Plus the fifteen correctness fixes from the full-codebase review (#18): ZoneInfo-aware binds, batch parameter-type unification, the sync-fast-path pool deadlock,
get_or_createconnection binding and root-filter inheritance, decode-plan snapshots, grouped-projection order_by annotations, and manager-scoped lazy relation reads.
Full details in CHANGELOG.md.
v1.14.3
Fixed
- Custom-
Prefetchcorrectness and performance. The custom-queryset M2M
prefetch path decodes through-table link values the way hydration does, so
pk types the driver returns in a non-native form (e.g. aCHAR(36)UUID pk
on MySQL/MariaDB) group correctly instead of silently producing empty
prefetched lists; the plain M2M join path decodes its owner-id column the
same way. A target shared by several owners now deep-copies mutable column
values (JSON dicts/lists), so mutating one owner's prefetched instance can
no longer leak into another's. Per-ownerLIMIT/OFFSETsemantics now
apply to every relation kind (reverse FK and forward FK, not just M2M),
and the per-owner queries run concurrently outside a transaction instead of
serially (no more N+1 latency for sliced prefetches). - Non-finite floats in JSON documents are rejected. Binding
NaN/±Infinityinside aJSONFieldvalue now raises a clear
ValueError(likejson.dumps(..., allow_nan=False)and PostgreSQL's
jsonb) instead of silently storing the strings"inf"/"NaN"(1.14.2)
ornull(≤ 1.14.1), both of which changed the member's type under readers
and filters with no decode path back. - SQL Server connection URLs. An explicit
trust_cert=trueis honoured
even withencrypt=strict, so "encryption required but trust the
(self-signed) server cert" stays expressible;encrypt=strictalone still
defaults to full certificate validation. Percent-decoding of URL
credentials is no longer lossy: a%-sequence that does not decode to
valid UTF-8 (a raw password merely containing%) passes through unchanged
instead of being rewritten to U+FFFD. - Primary-key migrations. Moving the pk between columns now emits the
demotingAlterFieldbefore the promoting one, soDROP PRIMARY KEYruns
beforeADD PRIMARY KEY("multiple primary keys" previously aborted the
migration when the promoted column diffed first). On MySQL/MariaDB,
demoting anAUTO_INCREMENTpk first restates the column via
MODIFY COLUMNto strip the flag (MySQL errno 1075 rejects dropping the
pk of a live auto column). bulk_create(update_fields=..., on_conflict=[])on SQL Server. An
explicit empty conflict target now takes the same unique-column
substitution as an omitted one, instead of rendering a MERGE that matches
on the uninserted auto pk column and failing.
yara-orm 1.14.2
Patch release: prefetch/dialect correctness fixes and hot-path optimizations.
Fixed
- Prefetch correctness — custom
Prefetchfilters/ordering honoured for M2M;LIMIT/OFFSET/slice on a custom M2MPrefetchapplies per owner; reverse-M2M managers read the cache underrelated_name(no more N+1). - Dialect / backend — PostgreSQL-only nested block comments (new
nests_block_commentsflag); MySQL/MariaDB escape backslashes in string literals; MSSQL percent-decodes URL credentials and honours?encrypt=strict; SQLite rolls back onCOMMITfailure; PostgreSQL clampsmax_sizeto>= 1. - Query / field — relation fields named like lookup operators (
slot__date) traverse correctly;FloatFieldcoerces numeric strings; non-finite floats in JSON params preserved as text across both binders. - Migrations / models — primary-key change diffing renders
ADD/DROP PRIMARY KEYper dialect;bulk_create(update_fields=..., on_conflict=[])falls back to the pk target; compiled insert plan snapshotted before awaiting (concurrent cross-dialect save safety).
Changed
- Hot-path optimizations — per-dialect compiled statement plan cache (O(1) restore); scalar-field compile path skips the relation probe; custom-M2M prefetch drops a redundant generator.
- SQLite benchmarks use
sync_fast_path— fastest on every SQLite op except the sub-millisecondgroup_by; SQLite/MariaDB tables and charts refreshed.
Full changelog: https://github.com/vsdudakov/yara-orm/blob/main/CHANGELOG.md