is there an auto update option for DateTimeField in peewee like TimeStamp in MySQL?
Asked Answered
K

4

24

I would like a timestamp field updating each time the record is modified like in MySQL.

DateTimeField(default=datetime.datetime.now()) will only set it the first time it is created...

Any have a simple solution? Is the only solution is to manually set the Column options in MySQL db?

Knowland answered 29/8, 2013 at 23:32 Comment(0)
C
39

You can override the save method on your model class.

class Something(Model):
    created = DateTimeField(default=datetime.datetime.now)
    modified = DateTimeField

    def save(self, *args, **kwargs):
        self.modified = datetime.datetime.now()
        return super(Something, self).save(*args, **kwargs)
Caroylncarp answered 30/8, 2013 at 12:53 Comment(4)
Please advise how to do same for updates e.g., Something.update(othercolumn=foo).where(id=2).execute(). Or do I need to rewrite my code to use Model.save() instead? Thx in advance.Quotable
If you're calling .update() then you may need to implement the timestamp updating logic on the SQL side. update() does not call save().Caroylncarp
Is there a way to override the Model class in Peewee?Libb
Jeff, Peewees models are just regular classes. You can subclass them (Ie create a BaseModel with various default fields, helper functions, etc).Syllabism
H
4

Just use TIMESTAMP type in MySQL. This field will update itself whenever the row is updated.

In the model:

last_updated = peewee.TimestampField()
Hageman answered 11/8, 2017 at 17:38 Comment(2)
Any tips for how I can do this for Postgresql?Dragnet
This is incorrect. This will store the current utc timestamp on create, but will NOT update it when the row is modified (unless you define an ON UPDATE constraint)Ching
F
1

You can also override the update method to provide.Just like what coleifer do:

class Something(Model):
    created = DateTimeField(default=datetime.datetime.now)
    modified = DateTimeField

    @classmethod
    def update(cls, *args, **kwargs):
        kwargs['modified'] = datetime.datetime.now()
        return super(Something, cls).save(*args, **kwargs)

    def save(self, *args, **kwargs):
        self.modified = datetime.datetime.now()
        return super(Something, self).save(*args, **kwargs)

You can also do the same thing on replace method

Fresher answered 26/12, 2018 at 7:49 Comment(2)
Bad idea. The SQL-generation methods should never be overridden (update, insert, select, etc).Caroylncarp
I would argue that if the logic is complex enough, adding it into such a "pre-save" step is acceptable. You just need to make sure you enforce using the right methods when CRUDing objects (e.g. update() and delete() should be avoided).Ching
A
1
from datetime import datetime

from peewee import (AutoField, CharField, DateTimeField, FloatField,
                    IntegerField, Model, MySQLDatabase, TextField, SQL)

from config import DataBaseConfig

mysql_client = MySQLDatabase(
    "your_database_name",
    host=DataBaseConfig.host,
    port=DataBaseConfig.port,
    user=DataBaseConfig.user,
    password=DataBaseConfig.password,
)

class CommonModel(Model):
    id = AutoField(verbose_name="primary key")
    create_time = DateTimeField(default=datetime.now, verbose_name="create time")
    update_time = DateTimeField(default=datetime.now, verbose_name="update time", constraints=[SQL('ON UPDATE CURRENT_TIMESTAMP')])

    class Meta:
        database = mysql_client

You can refer to this document. Single-column indexes and constraints!

Acea answered 23/1, 2023 at 12:56 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.