Search code examples
pythonpeeweemigrate

How to use `migrate()` in Peewee


I am new in peewee and I am very confused about migration. I tried the examples in the official documentation, and I got the results as follows:

from playhouse.migrate import *
from peewee import *

my_db = SqliteDatabase('my_database.db')
migrator = SqliteMigrator(my_db)

from peewee import *

database = SqliteDatabase('my_database.db')

class BaseModel(Model):
    class Meta:
        database = database

class Product(BaseModel):
    name = TextField()

    class Meta:
        table_name = 'product'

with my_db:
    my_db.create_tables([Product,])

Product.create(name = 'Big Peach')

price_field = IntegerField(default=0)
migrate(migrator.add_column('product', 'price', price_field))
db = migrator.database
columns = db.get_columns('product')
print(columns)

Here's what I got and the field of 'price' was added, indicating that migrated () is doing well:

[ColumnMetadata(name='id', data_type='INTEGER', null=False, primary_key=True, table='product', default=None), ColumnMetadata(name='name', data_type='TEXT', null=False, primary_key=False, table='product', default=None), ColumnMetadata(name='price', data_type='INTEGER', null=False, primary_key=False, table='product', default=None)]

Now the problem is that when I call Product.price,

query = Product.get(Product.name == 'Big Peach')
print(query.price)

the following result appears:

'Product' object has no attribute 'price'

I've tried another way to do this, in the command line:

python -m pwiz -e sqlite my_database.db

I got this:

from peewee import *

database = SqliteDatabase('my_database.db')

class UnknownField(object):
    def __init__(self, *_, **__): pass

class BaseModel(Model):
    class Meta:
        database = database

class Product(BaseModel):
    name = CharField()
    price = IntegerField()

    class Meta:
        table_name = 'product'   

I can use these to replace the previous Model, but there's no need to migrate(). So, my confusion is how to call the new field added by using migrate() in ONE .py file.


Solution

  • It's unusual to do this online:

    1. declare a model/schema
    2. migrate it
    3. use the new schema

    Because if you know you need a price field just put it on the model class from the start.

    If you really need to do this, then you can call this after you've run the migration:

    Product._meta.add_field('price', price_field)