临时数据库的Django自定义创建管理器逻辑

时间:2019-02-19 21:51:52

标签: django django-models django-managers temporal-database

我正在尝试开发一个Django应用程序,该应用程序具有围绕对象的时间状态的内置逻辑。期望能够具有表示资源的单个对象,同时具有该资源的属性能够随时间变化。例如,理想的用例是在任何给定时间(去年,昨天,明天,明年……)查询资源的owner

这就是我正在工作的...

class Resource(models.Model):                                       
    id = models.AutoField(primary_key=True)                         


class ResourceState(models.Model):                                  
    id = models.AutoField(primary_key=True)                         

    # Link the resource this state is applied to                    
    resource = models.ForeignKey(Resource, related_name='states', on_delete=models.CASCADE)

    # Track when this state is ACTIVE on a resource                 
    start_dt = models.DateTimeField()                               
    end_dt = models.DateTimeField()                                 

    # Temporal fields, can change between ResourceStates      
    owner = models.CharField(max_length=100)                        
    description = models.TextField(max_length=500)                 

我觉得我将不得不创建一个自定义界面来与该状态进行交互。一些示例用例(界面完全开放)...

# Get all of the states that were ever active on resource 1 (this is already possible)
Resource.objects.get(id=1).states.objects.all()

# Get the owner of resource 1 from the state that was active yesterday, this is non-standard behavior
Resource.objects.get(id=1).states.at(YESTERDAY).owner

# Create a new state for resource 1, active between tomorrow and infinity (None == infinity)
# This is obviously non standard if I want to enforce one-state-per-timepoint
Resource.objects.get(id=1).states.create(
    start_dt=TOMORROW,
    end_dt=None,
    owner="New Owner",
    description="New Description"
)

我觉得创建创建所需的定制逻辑量最大。 我要强制在任何给定时间点在ResourceState上只有一个Resource处于活动状态。这意味着要创建一些ResourceState对象,我需要调整/删除其他人。

>> resource = Resource.objects.get(id=1)
>> resource.states.objects.all()
[ResourceState(start_dt=None, end_dt=None, owner='owner1')]
>> resource.states.create(start_dt=YESTERDAY, end_dt=TOMORROW, owner='owner2')
>> resource.states.objects.all()
[
    ResourceState(start_dt=None, end_dt=YESTERDAY, owner='owner1'),
    ResourceState(start_dt=YESTERDAY, end_dt=TOMORROW, owner='owner2'), 
    ResourceState(start_dt=TOMORROW, end_dt=None, owner='owner1')
]

我知道我将不得不围绕定义逻辑进行大部分工作,但是应该在任何直观的地方放置它吗? Django是否为我提供了方便的位置来创建这些方法?如果是这样,在哪里应用它们的最佳位置?针对Resource对象?使用自定义Manager处理与相关“ ResourceState”对象的交互?

重新阅读上面的内容有点令人困惑,但这也不是一个简单的话题!!请让我知道是否有人对上述方法有任何想法!

一吨!

1 个答案:

答案 0 :(得分:1)

评论太久了,纯粹是一些想法,不是完整的答案,但是已经处理了金融系统中许多有效日期记录(在Django中不是),想到了一些事情:

我的直觉是将其放在资源模型的save方法上。您可能还需要定制管理器。

我可能还会对状态模型中的is_current布尔字段的想法调情,但是将来日期有效的状态记录需要考虑某些注意事项。如果一次只有一个活动状态,我还将检查是否需要结束日期。同时具有开始和结束绝对可以简化原始sql查询(如果需要的话):date() between state.start and state.end <-这将提供当前记录,任意日期的sub即可获取该日期的有效记录。另外,在您不知道结束日期的情况下,请考虑开放结束日期。您的查询将必须正确处理空值。您可能还需要考虑开放结束日期(例如,对于未知起始日期的大量历史数据)。我建议您不要使用某些超级早期日期作为填充(对于未知的结束日期,该日期与将来的日期相同)-如果您进行大量交易,则查询优化器可能会谢谢您,但是,我可能会变老了,这不再重要了。

如果您想了解这些内容,我建议您浏览https://www.amazon.ca/Art-SQL-Stephane-Faroult/dp/0596008945/和第6章中的1.8:

  

“但是在解决一个解决方案之前,我们必须承认   评估表有各种形状和大小。例如,   处理大量数据的电信公司拥有   相对短的价格表,不会经常更改。通过   相比之下,一家投资银行会存储所有证券的新价格,   衍生产品以及它可能处理的任何类型的金融产品   几乎连续。在一种情况下,好的解决方案并不一定   成为另一个很好的解决方案。

     

处理累积和更改的数据需要非常小心   设计和策略随变化率而变化。”