Migrating¶
Migrating from umongo 2 to umongo 3¶
For a full list of changes, see the CHANGELOG.
Database migration¶
Aside from changes in application code, migrating from umongo 2 to umongo 3 requires changes in the database.
The way the embedded documents are stored has changed. The _cls attribute is now only set on embedded documents that are subclasses of a concrete embedded document. Unless documents are non-strict (i.e. transparently handle unknown fields, default is strict), the database must be migrated to remove the _cls fields on embedded documents that are not subclasses of a concrete document.
This change is irreversible. It requires the knowledge of the application model (the document and embedded document classes).
umongo provides dedicated framework specific Instance
subclasses to help on
this.
A simple procedure to build a migration tool is to replace one’s Instance
class in the application code with such class and call
instance.migrate_2_to_3
on init.
For instance, given following umongo 3 application code
from umongo.frameworks.pymongo import PyMongoInstance
instance = PyMongoInstance()
# Register embedded documents
[...]
@instance.register
class Doc(Document):
name = fields.StrField()
# Embed documents
embedded = fields.EmbeddedField([...])
instance.set_db(pymongo.MongoClient())
# This may raise an exception if Doc contains embedded documents
# as described above
Doc.find()
the migration can be performed by calling migrate_2_to_3.
from umongo.frameworks.pymongo import PyMongoMigrationInstance
instance = PyMongoMigrationInstance()
# Register embedded documents
[...]
@instance.register
class Doc(Document):
name = fields.StrField()
# Embed documents
embedded = fields.EmbeddedField([...])
instance.set_db(pymongo.MongoClient())
instance.migrate_2_to_3()
# This is safe now that the database is migrated
Doc.find()
Of course, this needs to be done only once. Although the migration is idempotent, it wouldn’t make sense to keep this in the codebase and execute the migration on every application startup.
However, it is possible to embed the migration feature in the application code by defining a dedicated command, like a Flask CLI command for instance.