- Fixes for
playhouse.pwasyncio: report correct UPDATE / DELETE rowcounts on asyncpg, roll back open transactions when connections are returned to the pool, raise instead of deadlocking when querying duringiterate(), and detect the MySQL / MariaDB server version. - Additional
playhouse.pwasynciofixes: a seconditerate()on a busy connection raises instead of deadlocking, asyncpg exceptions are translated to peewee exception types, registered aggregates / collations / window functions / extensions andtimeoutare applied to async SQLite connections,:memory:databases use a single connection,atomic()accepts transaction arguments (e.g.lock_type), postgres connection URLs andisolation_levelare supported,%%in raw SQL is unescaped, and attempting a query outside the greenlet bridge no longer emits "never awaited" warnings. - Fixes for
playhouse.pydantic_utils: JSON fields validate asAny(now including the sqlite_extJSONField), foreign keys may be included / excluded by field name or column name, server-side defaults likeSQL('CURRENT_TIMESTAMP')are no longer emitted as schema defaults, andrelationshipskeys are validated. - Add a new cross-backend
JSONFieldto core that provides basic operations and also more consistent behavior when reading data. By default the new core JSONField treats extracted values as JSON, which is generally the correct thing, but "text-mode" is available as a chained.as_text()method. See docs. May eventually replace the backend-specific implementations with subclasses that inherit semantics of this new field. Note:playhouse.mysql_ext.JSONFieldis now the core field. The oldjson_dumps/json_loadsarguments are renameddumps/loads, theextract()method is removed (use item-access orpath()), and MySQL tables are now created withJSONcolumns rather thanTEXT. - Eliminate use of deprecated params when connecting to MySQL databases, thanks to @abulgher, #3050.
- Using
fromisoformat()ended up causing previously-unconverted strings (Ymd) to be converted in some cases, e.g. formatting a datetime as a str (#3051). The change I made to address this is to make explicit casts on function calls not attempt any heuristic python-value conversion. This makes it more natural to callfn.whatever().cast('text')and you predictably get text out.
