A simple and flexible migration manager for Peewee ORM.
- Version: 0.3.32
- Status: Development/Alpha
- Author: Churin Andrey
- python >= 3.5
- latest peewee
SQLite is not supported.
This package can be installed using pip:
$ pip install peewee-migrations
Run pem init
in the project root.
$ pem init
Configuration file 'migrations.json' was created.
Suppose we have Foo
model in models.py
class Foo(db.Model):
bar = peewee.CharField(max_length=50)
baz = peewee.IntegerField()
quux = peewee.IntegerField()
Add this model to the watch list and create migration.
$ pem add models.Foo
Model 'models.Foo' was added to the watch list.
$ pem watch
Migration `0001_migration_201807191008` has been created.
Now you can list available migrations:
$ pem list
[ ] 0001_migration_201807191008
Or view SQL that will be executed during migration:
$ pem show
[ ] 0001_migration_201807191008:
SQL> CREATE TABLE "foo" ("id" SERIAL NOT NULL PRIMARY KEY, "bar" VARCHAR(50) NOT NULL, "baz" INTEGER NOT NULL, "quux" INTEGER NOT NULL) []
PY> set_done('0001_migration_201807191008')
Use migrate
to run migrations:
$ pem migrate
[X] 0001_migration_201807191008
Change model Foo
class Foo(db.Model):
bar = peewee.CharField(max_length=20)
baz = peewee.IntegerField()
quux = peewee.IntegerField()
xyzzy = peewee.IntegerField()
and run watch
to create new migration:
$ pem watch
Migration `0002_migration_201807191036` has been created.
$ pem show
[ ] 0002_migration_201807191036:
SQL> ALTER TABLE "foo" ADD COLUMN "xyzzy" INTEGER []
SQL> ALTER TABLE "foo" RENAME COLUMN "bar" TO "old__bar" []
SQL> ALTER TABLE "foo" ADD COLUMN "bar" VARCHAR(20) []
SQL> UPDATE "foo" SET "xyzzy" = %s WHERE ("xyzzy" IS %s) [0, None]
SQL> UPDATE "foo" SET "bar" = SUBSTRING("old__bar", %s, %s) WHERE ("old__bar" IS NOT %s) [1, 20, None]
SQL> ALTER TABLE "foo" DROP COLUMN "old__bar" []
SQL> ALTER TABLE "foo" ALTER COLUMN "xyzzy" SET NOT NULL []
SQL> ALTER TABLE "foo" ALTER COLUMN "bar" SET NOT NULL []
PY> set_done('0002_migration_201807191036')
It's possible to create "serialized" migrations, run pem watch --serialize
. In this case, explicit migration functions will be additionally created.
$ pem watch --serialize
Migration `0001_migration_202112161523` has been created.
Additional code will be generated
...
def migrate_forward(op, old_orm, new_orm):
op.create_table(new_orm.foo)
def migrate_backward(op, old_orm, new_orm):
op.drop_table(old_orm.foo)
And after changing the model
$ pem watch --serialize
Migration `0002_migration_202112161527` has been created.
...
def migrate_forward(op, old_orm, new_orm):
op.add_column(new_orm.foo.xyzzy)
op.rename_column(old_orm.foo.bar, 'old__bar')
op.add_column(new_orm.foo.bar)
op.run_data_migration()
op.drop_column(old_orm.foo.bar)
op.add_not_null(new_orm.foo.xyzzy)
op.add_not_null(new_orm.foo.bar)
...
def migrate_backward(op, old_orm, new_orm):
op.rename_column(old_orm.foo.bar, 'old__bar')
op.add_column(new_orm.foo.bar)
op.run_data_migration()
op.drop_column(old_orm.foo.xyzzy)
op.drop_column(old_orm.foo.bar)
op.add_not_null(new_orm.foo.bar)
Serialized migrations are performed only according to the operations specified in the migrate functions.
To run migrations without a transaction, use pem migrate --autocommit
. To view a list of operations that will be performed in this mode, use pem show --autocommit
(some operations may differ).
For more information on using the commands see --help.
{
"prerun": "some code here", // some code to run before executing any command
"directory": "migrations", // folder to hold migrations
"history": "migratehistory", // table to hold migration history
"models": [ // list of models to watch
"module1.Model1",
"module2.Model2"
]
}