A project often undergoes changes related to database schema during course of its life. It may also be required patch existing data. Frappe bundles tools to handle these scenarios.
When you pull updates from any Frappe app (including Frappe), you should run
bench migrate to apply schema changes and data migrations if any.
You can edit a DocType to add, remove or change fields. On saving a DocType,
a JSON file containing the DocType data is added to source tree of your app.
When you add an app to a site, the DocTypes are installed using this JSON file.
For making schema changes, it's required to set
developer_mode in the
On running a sync (
bench migrate), doctypes in the system are synced to
their latest version from the JSON files in the app.
Note: Fields are soft deleted ie. the columns are not removed from the database table and however, they will not be visible in the documents. This is done to avoid any potential data loss situations and to allow you write related data migrations which might need values from deleted fields.
Note: Frappe doesn't support reverse schema migrations.
On introducing data related changes, you might want to run one off scripts to change existing data to match expectations as per new code.
To add a data migration to your code, you will have to write an
function to a python module and add it to
patches.txt of your app.
It is recommended to make a file with a patch number and name in its path and
add it to a patches package (directory) in your app. You can then add a line
with dotted path to the patch module to
The directory structure followed in Frappe is as below
frappe └── patches └── 4_0 └── my_awesome_patch.py
The patch can be added to
patches.txt by adding a line like
The metadata ie. DocType available in the execute function will be the latest as per JSON files in the apps. However, you will not be able to access metadata of any previous states of the system.
One off Python statements
You can also add one off python statements in
patches.txt using the syntax,
For example, execute:frappe.get_doc("User", "Guest").save()
Note: All lines in patches.txt have to be unique. If you want to run a line twice, you can make it unique by adding a distinct comment.