github coleifer/peewee 4.3.0

8 hours ago

Backwards-incompatible:

  • Specify requires-python >= 3.8. I've been putting off committing to anything like this, since technically we still work on 3.7, but 3.8 is the minimum we run on CI so it felt correct. * Replace docid implicit primary key on legacy FTSModel (FTS4) with rowid, which is equivalent. Using docid presents no benefit and switching to rowid makes operations more consistent. Users have a couple options when updating: * Explicitly add docid = DocIDField() to your FTSModel classes. * Update your code, replacing docid with rowid. The underlying data does not require a migration, as docid was just an alias for rowid.
  • When a RETURNING-clause insert of a single row inserts nothing, e.g. a conflict was ignored, execute() returns None on every backend.

Improvements:

  • Connection pools roll back transactions left open on check-in.
  • Pooled Postgres probes idle connections with SELECT 1 and discards dead ones, matching the MySQL pool's ping. Previously a connection terminated server-side while parked in the pool was handed out and failed on first use.
  • close_pool() in pwasyncio no longer spins the event loop on Python 3.13+ attempting to reclaim connections in use, and pool creation is now bounded by acquire_timeout. Connections terminated during shutdown are detected as stale and discarded at the next checkout.
  • JSONField negative path indexes render as $[last] / $[last-n] on MySQL/MariaDB. Previously the sqlite-only $[#-n] form was emitted, which MariaDB evaluates to NULL (overwriting the column when used with set()) and MySQL rejects as an invalid path.
  • JSONField mutators (set(), insert(), etc) store Python booleans as json true/false instead of the driver's 0/1, so values written by create() and by mutators compare consistently. Floats on MySQL/MariaDB likewise take their json text form, as MariaDB reformats driver floats in a way that breaks equality against the stored document.
  • Reflection/pwiz map MySQL JSON columns to the core JSONField instead of emitting from playhouse.mysql_ext import * for a re-exported field.
  • playhouse.pwasyncio logs to the peewee.pwasyncio logger rather than playhouse.pwasyncio.
  • Fix dataset freeze/thaw of NULL blob and datetime values. Empty CSV cells now import as NULL for non-text fields.
  • Lateral joins honor a user-supplied on= predicate instead of silently replacing it with true, and default to ON true when on= is omitted.
  • The SQLite FTS content option must be a Model or table-name string. Passing a Field now raises ImproperlyConfigured: it generated DDL that fts5 rejects outright and that fts4 silently truncated to the table name.
  • Fix FTS5Model.VocabModel(): term/col/offset were declared as virtual fields and omitted from default SELECTs, the instance-type model had the wrong column set, all three table-types shared one default table name, and the generated class was cached with whatever database was bound at first call. Vocab models are now built fresh per call with real fields, correct columns and per-type default names.
  • Add FTS5Model.web_query(), which translates the query syntax users expect from a search box (quoted phrases, AND/OR/NOT, -exclusion, column: filters and parentheses) into an FTS5 query. Anything else is searched as text, so covid-19 or c++ need no escaping, and the translation is always a valid query. The parser lives in the new playhouse.fts_parser module. Use it with search: Doc.search(Doc.web_query(user_input)).
  • Add FTS5Model.delete_command(), which removes a row using the fts5 delete command. This is how rows are removed from external-content and contentless tables, which need the originally-indexed values supplied back to them: sqlite treats an omitted column as NULL, and values that do not match what was indexed leave stale entries behind (undetectably so on a contentless table). Peewee therefore requires a value for every indexed column; pass None where NULL was indexed. The command exists only for those two configurations - default-storage and contentless_delete=1 tables reject it and use ordinary DELETE.
  • Add support for cysqlite's sick table func decorator syntax.
  • Better behavior for INSERT when as_rowcount() is specified, along with proper return of all parts of a composite PK instead of just the 1st column.
  • last_insert_id() is implemented once on Database, with backends overriding _last_insert_rowid() where the driver differs. APSW and the MariaDB connector inherit composite primary-key support as a result, having previously returned only the first column.
  • Don't apply field kwargs to barefield instances w/reflection, #3064.

View commits

7vSW35N

Don't miss a new peewee release

NewReleases is sending notifications on new releases.