Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically define fields in a peewee model

Tags:

python

peewee

This works:

class MyModel(peewee.Model):
    my_field = peewee.IntegerField(null=False, default=0)

    class Meta(object):
        database = db
        db_table = 'MyTable'

This does not work:

class MyModel(peewee.Model):

    class Meta(object):
        database = db
        db_table = 'MyTable'

setattr(MyModel, 'my_field', peewee.IntegerField(null=False, default=0))

I guess this is due to some metaclass magic done in peewee.Model. Indeed, I can't see it in the model's _meta.fields.

What would be a good way to define the fields dynamically?

like image 756
Bach Avatar asked Dec 02 '22 16:12

Bach


2 Answers

Instead of setattr, call add_to_class:

my_field = peewee.IntegerField(null=False, default=0)
my_field.add_to_class(MyModel, 'my_field_name')

# Now this works:
MyModel.my_field_name
like image 144
coleifer Avatar answered Dec 20 '22 07:12

coleifer


This post is just to give prominence to the correct answer given by AidanGawronski for Peewee 3.? (tested 2020-05-18).

Code such as the following succeeds:

class Note(Model):
    note_id = AutoField()
fields=('nx', 'ny', 'nz')
for f in fields:
    Note._meta.add_field(f, TextField(null=False))

Peewee's migrate module apparently can be used to accomplish the same thing, but I haven't tried it.

like image 27
Joan Eliot Avatar answered Dec 20 '22 09:12

Joan Eliot