0

我正在尝试开发一个 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可以在 a 上处于活动状态。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”对象的交互?

重新阅读上面的内容有点混乱,但这也不是一个简单的话题!!如果有人对如何执行上述操作有任何想法,请告诉我!

万分感谢!

4

1 回答 1

1

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

我的直觉是首先将它放在资源模型的保存方法上。您可能也需要一个自定义管理器。

我可能还会考虑在状态模型中使用 is_current 布尔字段的想法,但是对于未来日期有效的状态记录,需要考虑某些注意事项。如果一次只有一个活动状态,我还会检查是否需要结束日期。同时拥有 start 和 end 肯定会使原始 sql 查询(如果需要)更容易:date() between state.start and state.end<- 这将给出当前记录,分在任何日期以获得该日期的有效记录。此外,请考虑您不知道结束日期的开放式结束日期。您的查询必须正确处理空值。您可能还需要考虑开放式开始日期(例如,对于原始开始日期未知的大量历史数据)。我建议不要使用一些超早日期作为填充(对于未知结束日期的遥远未来日期也是如此) - 如果您最终有很多交易,您的查询优化器可能会感谢您,但是,我可能会变老了,这不再重要了。

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

“但在确定一种解决方案之前,我们必须承认估值表有各种形式和大小。例如,处理大量数据的电信公司的价格表相对较短,而且不会经常变化。相比之下,一家投资银行几乎连续不断地为所有证券、衍生品和任何类型的金融产品存储新价格。一种情况下的好解决方案不一定是另一种情况下的好解决方案。

处理累积和变化的数据需要非常仔细的设计和策略,这些策略会根据变化的速度而变化。”

于 2019-02-20T00:22:33.993 回答