1

Following this SO answer and using the (excellent) Peewee-ORM I'm trying to make a versioned database in which a history of a record is stored in a second _history table. So when I create a new using the create_table() method I also need to create a second table with four extra fields.

So let's say I've got the following table:

class User(db.Model):
    created = DateTimeField(default=datetime.utcnow)
    name = TextField()
    address = TextField()

When this table is created I also want to create the following table:

class UserHistory(db.Model):
    created = DateTimeField()  # Note this shouldn't contain a default anymore because the value is taken from the original User table
    name = TextField()
    address = TextField()
    # The following fields are extra
    original = ForeignKeyField(User, related_name='versions')
    updated = DateTimeField(default=datetime.utcnow)
    revision = IntegerField()
    action = TextField()  # 'INSERT' or 'UPDATE' (I never delete anything)

So I tried overriding the Model class like this:

class Model(db.Model):
    @classmethod
    def create_table(cls, fail_silently=False):
        db.Model.create_table(cls, fail_silently=fail_silently)

        history_table_name = db.Model._meta.db_table + 'history'

        # How to create the history table here?

As you can see I manage to create a variable with the history table name, but from there I'm kinda lost.

Does anybody know how I can create a new table which is like the original one, but just with the added 4 fields in there? All tips are welcome!

Community
  • 1
  • 1
kramer65
  • 50,427
  • 120
  • 308
  • 488

1 Answers1

0

Maybe something like this:

class HistoryModel(Model):
    @classmethod
    def create_table(cls...):
        # Call parent `create_table()`.
        Model.create_table(cls, ...)

        history_fields = {
            'original': ForeignKeyField(cls, related_name='versions'),
            'updated': DateTimeField(default=datetime.utcnow),
            'revision': IntegerField(),
            'action': TextField()}
        model_name = cls.__name__ + 'History'
        HistoryModel = type(model_name, (cls,), history_fields)
        Model.create_table(HistoryModel, ...)

Also note you'll want to do the same thing for create_indexes().

I'd suggest creating a property or some other way to easily generate the HistoryModel.

coleifer
  • 24,887
  • 6
  • 60
  • 75