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. * Replacedocidimplicit primary key on legacyFTSModel(FTS4) withrowid, which is equivalent. Usingdocidpresents no benefit and switching torowidmakes operations more consistent. Users have a couple options when updating: * Explicitly adddocid = DocIDField()to your FTSModel classes. * Update your code, replacingdocidwithrowid. 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()returnsNoneon every backend.
Improvements:
- Connection pools roll back transactions left open on check-in.
- Pooled Postgres probes idle connections with
SELECT 1and 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 byacquire_timeout. Connections terminated during shutdown are detected as stale and discarded at the next checkout.JSONFieldnegative 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 withset()) and MySQL rejects as an invalid path.JSONFieldmutators (set(),insert(), etc) store Python booleans as json true/false instead of the driver's 0/1, so values written bycreate()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
JSONFieldinstead of emittingfrom playhouse.mysql_ext import *for a re-exported field. playhouse.pwasynciologs to thepeewee.pwasynciologger rather thanplayhouse.pwasyncio.- Fix
datasetfreeze/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 withtrue, and default toON truewhenon=is omitted. - The SQLite FTS
contentoption must be a Model or table-name string. Passing a Field now raisesImproperlyConfigured: 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, socovid-19orc++need no escaping, and the translation is always a valid query. The parser lives in the newplayhouse.fts_parsermodule. Use it with search:Doc.search(Doc.web_query(user_input)). - Add
FTS5Model.delete_command(), which removes a row using the fts5deletecommand. 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; passNonewhere NULL was indexed. The command exists only for those two configurations - default-storage andcontentless_delete=1tables reject it and use ordinaryDELETE. - 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 onDatabase, 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.
