我正在为SQLAlchemy编写审计mixin,但不确定如何确切地实现。
我的类看起来像这样:
class AuditColumns(object):
created_dt = Column(DateTime,
default=datetime.utcnow(),
nullable=False)
created_by = Column(String(64),
default=current_user,
nullable=False)
updated_dt = Column(DateTime,
default=datetime.utcnow(),
nullable=False,
onupdate=datetime.utcnow())
updated_by = Column(String(64),
default=current_user,
nullable=False,
onupdate=current_user)
更新的内容都很好,因为我只需要在表级别记录最新的更新;任何重要的审计都将在一个单独的表中进行,详细说明更新/删除等操作。
我的问题是:我不想更新created_dt/by列。我知道,在我的代码中,当更新对象时,我可以简单地省略它们;但是另一个编码人员可能会这样做;因此,我真的希望在每次更新之前,要么确保它覆盖自身的值,要么如果有人试图更改它,则引发错误(后者更可取)。
我的SQLAlchemy技能仍在发展中,事件是否是找出解决方案的地方?还是有什么可以通过覆盖一些通用的声明性函数(如save()或before_save()或任何可能存在的函数)来完成的?
我会继续寻找答案-但帮助找到解决方案(我更喜欢不给出代码)是更可取的。
onupdate=datetime.datetime.utcnow
没有生效。 - Vikas Prasadcreated_at = db.Column(db.DateTime, server_default=UtcNow())
和updated_at = db.Column(db.DateTime, server_default=UtcNow(), onupdate=UtcNow())
,其中UtcNow
是一个类,如下所示:class UtcNow(expression.FunctionElement): type = DateTime()
,而我们有@compiles(UtcNow, 'postgresql') def pg_utc_now(element, compiler, **kw): return "TIMEZONE('utc', CURRENT_TIMESTAMP)"
。 - Vikas Prasad