Backwards-incompatible:
- MySQL and MariaDB connections no longer set
sql_mode. Peewee had been settingPIPES_AS_CONCAT, but the param replaced the server's mode rather than adding to it, which silently disabledSTRICT_TRANS_TABLES(etc). Going forward Peewee will not modifysql_modeby default and useCONCAT()rather than||for MySQL/MariaDB. - MySQL and MariaDB connection charset defaults to
utf8mb4instead ofutf8, which is an alias forutf8mb3and cannot store 4-byte characters. - A field's
sequence=is now qualified with the model'sMeta.schema. If the name you pass already contains a dot it is treated as fully-qualified and used as-is, sosequence='other.seq'is unaffected byMeta.schema. Also,sequence_exists()accepts a schema-qualified name. - SQLite
BEGIN,COMMITandROLLBACKare issued directly on a cursor rather than throughexecute_sql(), so they are no longer debug-logged, do not fire query hooks and are not counted bycount_queries(). This matches Postgres and MySQL. atomic()andtransaction()on a closed database withautoconnect=Falsenow raiseInterfaceErroron Postgres and MySQL, as they already did on SQLite (and as queries do). Previouslybegin()opened a connection regardless ofautoconnect.
Improvements:
- Add
SqliteDatabase(..., lock_type=...)to set the default locking strategy for transactions that do not specify one, e.g.lock_type='IMMEDIATE'. - Postgres introspection (
get_tables(),get_columns(),get_indexes(),get_primary_keys(),get_foreign_keys(),get_views()) with noschemanow follows the search path viacurrent_schema()instead of assumingpublic, matching MySQL'sDATABASE()behavior. - Add
Runner(db, schema=...)andpwmigrate --schemafor running migrations against a specific schema. The history table lives in that schema, so each schema tracks its own applied set and one set of migration files can be run against any number of schemas. - Add
SchemaMigrator(db, schema=...), which qualifies every table name w/the given schema (or database on MySQL). Not supported for SQLite, as the table-rebuild rewrites DDL straight fromsqlite_master. - Add
websearch=TruetoTSVectorField.match()andMatch()to parse the query usingwebsearch_to_tsquery()(pg 11+). Accepts user input without raising (quoted phrases,or, and-negation). - Add
Database.query_hooks, a list of callables invoked after every query with aQueryEventnamed tuple (sql,params,duration,exception), on success and failure both. No timing overhead when the list is empty. - Add
Database.after_commit(fn), which runs a callable after the outermost transaction commits. Hook is discarded on rollback and runs immediately if no transaction is active. Use for, e.g., writing a row PK to a task queue. - Add
EnumFieldandIntEnumFieldtoplayhouse.fields, storingmember.valueand returning the member, rejecting unknown values on write and comparison.to_pydantic()maps any field with anenum_classattribute to the enum itself, so schemas validate membership. - Add
Database.dispose()/PooledDatabase.dispose()for discarding and resetting local connection state, e.g. in a child process afterfork(). Model.bind_ctx()andDatabase.bind_ctx()can be used as decorators, like the other peewee context-managers. Previously the decorator form raisedTypeError: '_BoundModelsContext' object is not callable.TimeFieldsupports utc offsets likeDateTimeField, parsing e.g.'11:12:13+02:00'to an awaredatetime.timeinstead of returningstr. Only sqlite stores the offset. The postgres/mysql drivers drop it on write.
