跳转到主要内容

使用数据库触发器的高效模型历史记录

项目描述

Django Chronicle是一种使用数据库触发器实现的缓慢变化维度类型4的实现。

如何使用?

  1. 创建一个自定义修订模型。例如:

    from chronicle.models import AbstractRevision
    
    class Revision(AbstractRevision):
        user = models.ForeignKey(settings.AUTH_USER_MODEL)
        created = models.DateTimeField(auto_now_add=True)
    
  2. settings.REVISION_MODEL 设置为指向您的修订模型。例如:

    REVISION_MODEL = 'revision.Revision'
    
  3. 让您的模型继承自 HistoryMixin。例如:

    from chronicle.models import HistoryMixin
    from django.db import models
    
    class Food(HistoryMixin, models.Model):
        name = models.CharField(max_length=50)
    
  4. 创建所有迁移并运行它们

    $ manage.py makemigrations
    $ manage.py migrate
    

    这应该为继承自 HistoryMixin 的模型创建所有 _history 表。

  5. 创建数据库触发器

    $ manage.py create_history_triggers
    

现在,对您的模型的任何更改都应该记录在 _history 表中,您可以通过 History 模型访问模型历史,该模型成为原始类的字段。

示例用法

# create
food = Food('Carot')
food.save()
assert(Food.History.objects.filter(id=food.id).count() == 1)

# update
food.name = 'Carrot'
food.save()
assert(Food.History.objects.filter(id=food.id).count() == 2)

# delete
food.delete()
assert(Food.History.objects.filter(id=food.id).count() == 3)

为什么使用数据库触发器?

实现模型历史记录的最明显选择是将信号处理程序连接到 post_savepost_delete 信号。这有一些相当大的缺点

1.) QuerySet.update() 和许多其他的 QuerySet 方法都不会发出任何信号。仅使用 save() 限制代码可能会导致巨大的性能问题,这取决于应用程序的类型。

2.) 通过 Django ORM 创建历史记录时会有相当大的性能影响。单个 QuerySet.update() 调用可能会导致数百或数千次插入。虽然这可以通过使用 Manager.bulk_create 方法来解决,但数据库触发器要快得多,因为它不需要额外的数据库往返。

3.) 这适用于任何类型的原始查询 - 即使是在 Django ORM 之外 - 只要正确设置了 chronicle.revision_id 会话变量。

唯一的真正缺点是数据库兼容性。目前,此包仅支持 PostgreSQL 数据库引擎。

如何在不使用 Django ORM 的情况下发出查询?

通过在版本表中插入一行来创建一个版本,并像这样设置 chronicle.revision_id 会话变量:

SET chronicle.revision_id = 42; -- replace 42 by the actual revision id

一旦你对模型的所有更改都已完成,不要忘记重置会话变量。否则,你可能会在同一个数据库会话中意外地重复使用相同的版本。

SET chronicle.revision_id TO DEFAULT;

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源分布

django_chronicle-0.2.0.tar.gz (12.7 kB 查看散列)

上传时间

构建分布

django_chronicle-0.2.0-py3-none-any.whl (10.7 kB 查看散列)

上传时间 Python 3

支持者