-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(statistics): introduce a statistics base model based on SQL …
…VIEW This is still WIP, but I think this is the right way forward. TODO: * Further refactor the views, as the customer,project,task viewsets should return all the selected objects, regardless of reported sum. I think we will need to base those viewsets off of their respective models and join/prefetch the report statistic onto it * Finalize the rest of the refactoring to make it work again Optionally (and I hope it's not necessary): Build a statistic (database) view for all statistics endpoints. This would allow us to optimize the whole thing much more (and improve performance AND readability) at the cost of quite some more boilerplate code
- Loading branch information
Showing
7 changed files
with
143 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
backend/timed/reports/migrations/0001_initial_create_analysis_view.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
from django.db import migrations, models | ||
|
||
CREATE_VIEW_SQL = """ | ||
CREATE VIEW "reports_reportstatistic" AS ( | ||
SELECT | ||
task_id as id, -- avoid jumping through hoops for Django | ||
task_id, | ||
user_id, | ||
projects_project.id as project_id, | ||
projects_project.customer_id as customer_id, | ||
sum(duration) as duration, | ||
date, | ||
to_char(date, 'YYYY') as year, | ||
to_char(date, 'YYYY-MM') as month | ||
FROM tracking_report | ||
JOIN projects_task ON projects_task.id = tracking_report.task_id | ||
JOIN projects_project ON projects_project.id = projects_task.project_id | ||
GROUP BY | ||
task_id, | ||
user_id, | ||
date, | ||
projects_task.id, | ||
projects_project.id, | ||
projects_project.customer_id | ||
) | ||
""" | ||
|
||
DROP_VIEW_SQL = """ | ||
DROP VIEW "reports_reportstatistic" | ||
""" | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('tracking', '0001_initial') | ||
] | ||
|
||
operations = [ | ||
migrations.RunSQL(CREATE_VIEW_SQL, DROP_VIEW_SQL), | ||
migrations.CreateModel( | ||
name='reportstatistic', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('duration', models.DurationField()), | ||
('month', models.CharField(max_length=7)), | ||
('year', models.CharField(max_length=4)), | ||
], | ||
options={ | ||
'managed': False, | ||
}, | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
from django.db import models | ||
|
||
from timed.employment.models import User | ||
from timed.projects.models import Customer, Project, Task | ||
|
||
|
||
class ReportStatistic(models.Model): | ||
# Implement a basic STAR SCHEMA view: Basic aggregate is done in the VIEW, | ||
# everything else of interest can be JOINed directly | ||
|
||
task = models.OneToOneField( | ||
Task, on_delete=models.DO_NOTHING, null=False, related_name="+" | ||
) | ||
user = models.ForeignKey(User, on_delete=models.DO_NOTHING, null=False) | ||
project = models.ForeignKey(Project, on_delete=models.DO_NOTHING, null=False) | ||
customer = models.ForeignKey(Customer, on_delete=models.DO_NOTHING, null=False) | ||
duration = models.DurationField() | ||
|
||
month = models.CharField(max_length=7) | ||
year = models.CharField(max_length=4) | ||
date = models.DateField() | ||
|
||
class Meta: | ||
managed = False | ||
|
||
def __str__(self): | ||
return f"ReportStat({self.task} @ {self.date}, {self.user})" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters