The 4.0 release includes some minor backwards-incompatible fixes (hence the major version number bump) and introduces three major new features:
- Database migrations, providing a structured mechanism for evolving a project’s schema over time. (#752)
- Nested transaction support via
db.atomic(), plus numerous improvements to how transactions work across the library. (#755) - Support for compound foreign keys, including creation, transformation and introspection through table.foreign_keys. (#594)
Other notable changes include:
- Upserts now use SQLite’s
INSERT ... ON CONFLICT ... DO UPDATE SETsyntax, detect existing table primary keys automatically and reject records that are missing required primary key values. (#652) db.query()now executes immediately and rejects statements that do not return rows; usedb.execute()for writes and DDL.- CSV and TSV imports now detect column types by default, while inserts into existing tables preserve those tables’ column types. (#679)
- Foreign key handling now preserves
ON DELETE/ON UPDATEactions during transforms and resolves referenced primary keys more accurately. (#530) - Column names passed to Python API methods are now matched case-insensitively, mirroring SQLite’s own identifier behavior. (#760)
- The command-line tool now emits UTF-8 JSON output by default, with
--asciiavailable to restore escaped output. (#625) table.extract()andextracts=no longer create lookup table records for all-nullvalues. (#186)
See Upgrading from 3.x to 4.0 for details on backwards-incompatible changes.
The detailed release notes for the features and fixes shipped during the 4.0 pre-release cycle are available in 4.0a0, 4.0a1, 4.0rc1, 4.0rc2, 4.0rc3 and 4.0rc4.