使用数据库触发器的高效模型历史记录
项目描述
Django Chronicle是一种使用数据库触发器实现的缓慢变化维度类型4的实现。
如何使用?
-
创建一个自定义修订模型。例如:
from chronicle.models import AbstractRevision class Revision(AbstractRevision): user = models.ForeignKey(settings.AUTH_USER_MODEL) created = models.DateTimeField(auto_now_add=True)
-
将
settings.REVISION_MODEL
设置为指向您的修订模型。例如:REVISION_MODEL = 'revision.Revision'
-
让您的模型继承自
HistoryMixin
。例如:from chronicle.models import HistoryMixin from django.db import models class Food(HistoryMixin, models.Model): name = models.CharField(max_length=50)
-
创建所有迁移并运行它们
$ manage.py makemigrations $ manage.py migrate
这应该为继承自
HistoryMixin
的模型创建所有_history
表。 -
创建数据库触发器
$ 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_save
和 post_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 的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | 05d8370741493d01587ef6384844c4fecccb13f91079385b07d6453c0ec11dd1 |
|
MD5 | 223a6d3524cfa4748dc25339d154cd8a |
|
BLAKE2b-256 | ec120ec9869d45ef988aaa4f678b1ef251f6310c8c6103cee8fae1cb201561f1 |
django_chronicle-0.2.0-py3-none-any.whl 的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | 8b1cab138e7cc1e148d246a80f278650af26dcff93feedee78cb08342954c1f9 |
|
MD5 | 2840b47af1c493feea66da33572bf3e7 |
|
BLAKE2b-256 | f2dd3369a8aeb927132fea0cc00c4eae893748de282189f3ff0c9d3d8025df96 |