Django настраиваемая логика менеджера создания для временной базы данных - PullRequest
0 голосов
/ 20 февраля 2019

Я пытаюсь разработать приложение 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 голосов
/ 20 февраля 2019

слишком долго для комментария, и только некоторые мысли, не полный ответ, но, имея дело со многими записями, действующими на дату в финансовых системах (не в Django), некоторые вещи приходят на ум:

Моя интуиция могла быначать с установки метода сохранения модели ресурсов.Возможно, вы правы и в том, что вам нужен пользовательский менеджер.

Возможно, я бы также заиграл с идеей логического поля is_current в модели состояний, но необходимо учитывать определенные меры предосторожности в будущих записях о состоянии состояний.,Если есть только одно активное состояние за один раз, я бы также рассмотрел необходимость конечной даты.Наличие как начала, так и конца определенно упрощает необработанные запросы sql (если они когда-либо понадобятся): date() between state.start and state.end <- это даст текущую запись, подпрограмму на любую дату, чтобы получить эффективную запись этой даты.Кроме того, обратите внимание на дату окончания открытого конца, когда вы не знаете дату окончания.Ваши запросы должны правильно обрабатывать нули.Возможно, вам также может понадобиться рассмотреть дату начала с открытым окончанием (скажем, для загрузки исторических данных, где первоначальная дата начала неизвестна).Я бы рекомендовал избегать использования какой-либо суперранней даты в качестве заполнения (то же самое относится и к дате в далеком будущем для неизвестных дат окончания). Если у вас много транзакций, ваш оптимизатор запросов может поблагодарить вас, однако я могубыть старым, и это больше не имеет значения. </p>

Если вы хотите прочитать об этом материале, я бы рекомендовал взглянуть на 1,8 в https://www.amazon.ca/Art-SQL-Stephane-Faroult/dp/0596008945/ и главу 6:

"Но прежде чем принять решение об одном решении, мы должны признать, что таблицы оценки бывают всех форм и размеров. Например, таблицы телекоммуникационных компаний, которые обрабатывают огромные объемы данных, имеют относительно короткий прайс-лист, который не меняетсяочень часто. В отличие от этого, инвестиционный банк хранит новые цены на все ценные бумаги, деривативы и любой тип финансового продукта, с которым он может иметь дело почти постоянно. Хорошее решение в одном случае не обязательно будет хорошим решением в другом *.1013 *

Обработка данных, которые накапливаются и изменяются, требует очень тщательного проектирования и тактики, которыет меняется в зависимости от скорости изменения. "

...