OnUPDATE不覆盖当前日期时间值 [英] onupdate not overridinig current datetime value

查看:0
本文介绍了OnUPDATE不覆盖当前日期时间值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为SQLAlChemy编写一个审核混合,但我不确定具体如何做到这一点。

我的类如下所示:

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()或任何可能存在的函数)来完成此任务?

我将继续寻找答案-但帮助寻找解决方案(我不希望得到代码)是更可取的。

推荐答案

[编辑] 我使用的是flask.g--但我已经意识到,除非在某个地方进行硬编码,否则它不是持久的;因此,我在实际实现中转向了用户会话 [/编辑]

好了,伙计们..。希望这会对某些人有所帮助。我想我已经整理出了解决方案,经过测试,对我的项目来说足够安全(尽管它并不完美,我希望得到一些反馈):

以下是审核混合:

from datetime import datetime
from flask import g
from sqlalchemy import Column, DateTime, String
from sqlalchemy.orm import MapperExtension


class AuditColumns(object):

    created_dt = Column(DateTime,
                        default=datetime.utcnow(),
                        nullable=False)

    created_by = Column(String(64),
                        nullable=False)

    updated_dt = Column(DateTime,
                        default=datetime.utcnow(),
                        nullable=False,
                        onupdate=datetime.utcnow())

    updated_by = Column(String(64),
                        nullable=False)


class AuditExtension(MapperExtension):

    def before_insert(self, mapper, connection, instance):
        """ Make sure the audit fields are set correctly  """
        instance.created_dt = datetime.utcnow()
        instance.created_by = g.username

        instance.updated_dt = datetime.utcnow()
        instance.updated_by = g.username

    def before_update(self, mapper, connection, instance):
        """ Make sure when we update this record the created fields stay unchanged!  """
        instance.created_dt = instance.created_dt
        instance.created_by = instance.created_by

        instance.updated_dt = datetime.utcnow()
        instance.updated_by = g.username

然后我只需将扩展和基本扩展添加到任何需要它们的模型上:

class Roles(db.Model, AuditColumns):

    id = Column(BigInteger, primary_key=True)
    username = Column(String(64), nullable=False, unique=True)
    password = Column(String(255), nullable=False)

    __mapper_args__ = {
        'extension': AuditExtension()}

    def __repr__(self):
        return self.username
现在,我注意到这种方法有两个警告: -g.Username是硬编码的-在这个阶段,我不知道如何通过SQLAlChemy传递额外的参数以在映射器中使用,所以现在;这将是必须的。 -仍然可以进行数据库级别的操作...在数据库上运行原始SQL不会阻止更新这些列。

第二个警告是有问题的,但我认为定义模型级别的触发器可能有助于防止任何数据库交互错误。

有没有其他方法的想法?我想我已经锁定了所有基于SQLalChemy的小工具...

这篇关于OnUPDATE不覆盖当前日期时间值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆