1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-04-15 01:28:30 +00:00

Resolve "Fix formula with now and field functions not always periodically refreshing"

This commit is contained in:
Davide Silvestri 2023-03-29 14:28:09 +00:00
parent 536e8fdbdd
commit e2fb997a30
4 changed files with 44 additions and 28 deletions
backend
src/baserow/contrib/database/fields
tests/baserow/contrib/database/field
changelog/entries/unreleased/bug
premium/backend/tests/baserow_premium_tests/api/views/views

View file

@ -15,16 +15,7 @@ from django.contrib.postgres.fields import JSONField
from django.core.exceptions import ValidationError
from django.core.files.storage import Storage, default_storage
from django.db import OperationalError, models
from django.db.models import (
CharField,
Count,
DateTimeField,
F,
Func,
Q,
QuerySet,
Value,
)
from django.db.models import CharField, DateTimeField, F, Func, Q, QuerySet, Value
from django.db.models.functions import Coalesce
from django.utils.timezone import make_aware
@ -3275,12 +3266,7 @@ class FormulaFieldType(ReadOnlyFieldType):
return False
def get_fields_needing_periodic_update(self) -> Optional[QuerySet]:
return (
FormulaField.objects.filter(needs_periodic_update=True)
.annotate(num_dependencies=Count("field_dependencies"))
.filter(num_dependencies=0)
)
return FormulaField.objects.filter(needs_periodic_update=True)
def run_periodic_update(
self,

View file

@ -6,6 +6,7 @@ import pytest
import pytz
from freezegun import freeze_time
from baserow.contrib.database.fields.field_types import FormulaFieldType
from baserow.contrib.database.fields.tasks import run_periodic_fields_updates
@ -144,7 +145,7 @@ def test_run_field_type_updates_dependant_fields(data_fixture):
def test_workspace_updated_last_will_be_updated_first_this_time(data_fixture):
user = data_fixture.create_user()
def create_table_with_row_in_workspace(workspace):
def create_table_with_now_in_workspace(workspace):
database = data_fixture.create_database_application(workspace=workspace)
table = data_fixture.create_database_table(database=database)
formula_field = data_fixture.create_formula_field(
@ -157,7 +158,7 @@ def test_workspace_updated_last_will_be_updated_first_this_time(data_fixture):
workspace_updated_most_recently = data_fixture.create_workspace(user=user)
workspace_updated_most_recently.now = now
workspace_updated_most_recently.save()
table_model, formula_field = create_table_with_row_in_workspace(
table_model, formula_field = create_table_with_now_in_workspace(
workspace_updated_most_recently
)
row = table_model.objects.create()
@ -168,7 +169,7 @@ def test_workspace_updated_last_will_be_updated_first_this_time(data_fixture):
)
workspace_that_should_be_updated_first_this_time.now = a_day_ago
workspace_that_should_be_updated_first_this_time.save()
table_model_2, formula_field_2 = create_table_with_row_in_workspace(
table_model_2, formula_field_2 = create_table_with_now_in_workspace(
workspace_that_should_be_updated_first_this_time
)
row_2 = table_model_2.objects.create()
@ -198,7 +199,7 @@ def test_workspace_updated_last_will_be_updated_first_this_time(data_fixture):
def test_one_formula_failing_doesnt_block_others(data_fixture):
user = data_fixture.create_user()
def create_table_with_row_in_workspace(workspace):
def create_table_with_now_in_workspace(workspace):
database = data_fixture.create_database_application(workspace=workspace)
table = data_fixture.create_database_table(database=database)
formula_field = data_fixture.create_formula_field(
@ -211,7 +212,7 @@ def test_one_formula_failing_doesnt_block_others(data_fixture):
second_updated_workspace = data_fixture.create_workspace(user=user)
second_updated_workspace.now = now
second_updated_workspace.save()
table_model, working_other_formula = create_table_with_row_in_workspace(
table_model, working_other_formula = create_table_with_now_in_workspace(
second_updated_workspace
)
row = table_model.objects.create()
@ -220,7 +221,7 @@ def test_one_formula_failing_doesnt_block_others(data_fixture):
first_updated_workspace = data_fixture.create_workspace(user=user)
first_updated_workspace.now = a_day_ago
first_updated_workspace.save()
table_model_2, broken_first_formula = create_table_with_row_in_workspace(
table_model_2, broken_first_formula = create_table_with_now_in_workspace(
first_updated_workspace
)
row_2 = table_model_2.objects.create()
@ -249,3 +250,29 @@ def test_one_formula_failing_doesnt_block_others(data_fixture):
assert first_updated_workspace.now != a_day_ago
assert second_updated_workspace.now != now
assert first_updated_workspace.now < second_updated_workspace.now
@pytest.mark.django_db
def test_all_formula_that_needs_updates_are_periodically_updated(data_fixture):
workspace = data_fixture.create_workspace()
database = data_fixture.create_database_application(workspace=workspace)
table = data_fixture.create_database_table(database=database)
with freeze_time("2023-02-27 10:15"):
now_field = data_fixture.create_formula_field(
table=table, formula="now()", date_include_time=True
)
data_fixture.create_formula_field(
table=table,
formula=f"field('{now_field.name}')",
date_include_time=True,
)
date_field = data_fixture.create_date_field(table=table, date_include_time=True)
data_fixture.create_formula_field(
table=table,
formula=f"now() > field('{date_field.name}')",
date_include_time=True,
)
assert FormulaFieldType().get_fields_needing_periodic_update().count() == 3

View file

@ -0,0 +1,7 @@
{
"type": "bug",
"message": "fix formula with now and field functions not always periodically refreshing",
"issue_number": 1650,
"bullet_points": [],
"created_at": "2023-03-29"
}

View file

@ -1,4 +1,3 @@
from random import randrange
from urllib.parse import urlencode
from django.conf import settings
@ -17,6 +16,7 @@ from rest_framework.status import (
HTTP_404_NOT_FOUND,
)
from baserow.contrib.database.fields.field_types import TextFieldType
from baserow.contrib.database.fields.registries import field_type_registry
from baserow.contrib.database.views.models import View
from baserow.test_utils.helpers import is_dict_subset
@ -35,9 +35,6 @@ def get_list_url(calendar_view_id: int) -> str:
)
# premium licenses
@pytest.mark.django_db
@pytest.mark.view_calendar
@override_settings(DEBUG=True)
@ -566,7 +563,6 @@ def test_create_calendar_view_different_field_types(api_client, premium_data_fix
}
all_field_types = field_type_registry.get_all()
date_field_types = [t for t in all_field_types if t.can_represent_date]
other_field_types = [t for t in all_field_types if not t.can_represent_date]
for date_field_type in date_field_types:
field = date_field_type.model_class.objects.create(**kwargs)
@ -584,7 +580,7 @@ def test_create_calendar_view_different_field_types(api_client, premium_data_fix
)
assert response.status_code == HTTP_200_OK
not_compatible_field_type = other_field_types[randrange(0, len(other_field_types))]
not_compatible_field_type = field_type_registry.get(TextFieldType.type)
field = not_compatible_field_type.model_class.objects.create(**kwargs)
premium_data_fixture.create_model_field(kwargs["table"], field)