1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-04-08 06:40:07 +00:00

Merge branch 'fix-error-trashed-data-sync-property-field' into 'develop'

Fix error when syncing a table with a trashed field

See merge request 
This commit is contained in:
Bram Wiepjes 2025-02-13 19:29:49 +00:00
commit 82d011a5c1
5 changed files with 126 additions and 4 deletions
backend
src/baserow/contrib/database/data_sync
tests/baserow/contrib/database/data_sync
changelog/entries/unreleased/bug
enterprise/backend
src/baserow_enterprise/data_sync
tests/baserow_enterprise_tests/data_sync

View file

@ -514,9 +514,12 @@ class DataSyncHandler:
enabled_properties = DataSyncSyncedProperty.objects.filter(
data_sync=data_sync,
field__trashed=False,
).prefetch_related(
Prefetch("field", queryset=specific_queryset(Field.objects.all())),
# Deliberately using the trashed fields. They still synced because the
# user has the ability to restore them.
Prefetch(
"field", queryset=specific_queryset(Field.objects_and_trash.all())
),
"field__select_options",
)
enabled_properties_per_key = {p.key: p for p in enabled_properties}

View file

@ -1673,7 +1673,7 @@ def test_delete_non_unique_primary_data_sync_field(data_fixture):
@pytest.mark.django_db
@responses.activate
def test_delete_field_and_then_sync(data_fixture):
def test_trash_field_and_then_sync(data_fixture):
responses.add(
responses.GET,
"https://baserow.io/ical.ics",
@ -1702,6 +1702,82 @@ def test_delete_field_and_then_sync(data_fixture):
assert data_sync.last_error is None
@pytest.mark.django_db
@responses.activate
def test_trash_field_is_synced(data_fixture):
responses.add(
responses.GET,
"https://baserow.io/ical.ics",
status=200,
body=ICAL_FEED_WITH_ONE_ITEMS,
)
responses.add(
responses.GET,
"https://baserow.io/ical2.ics",
status=200,
body=ICAL_FEED_WITH_TWO_ITEMS,
)
user = data_fixture.create_user()
database = data_fixture.create_database_application(user=user)
handler = DataSyncHandler()
data_sync = handler.create_data_sync_table(
user=user,
database=database,
table_name="Test",
type_name="ical_calendar",
synced_properties=["uid", "dtstart"],
ical_url="https://baserow.io/ical.ics",
)
data_sync = handler.sync_data_sync_table(user=user, data_sync=data_sync)
data_sync.ical_url = "https://baserow.io/ical2.ics"
data_sync.save()
fields = specific_iterator(data_sync.table.field_set.all().order_by("id"))
FieldHandler().delete_field(user, fields[1])
data_sync = handler.sync_data_sync_table(user=user, data_sync=data_sync)
model = data_sync.table.get_model()
rows = model.objects.all()
assert getattr(rows[1], f"field_{fields[1].id}") == datetime(
2024, 9, 2, 11, 0, tzinfo=timezone.utc
)
@pytest.mark.django_db
@responses.activate
def test_set_data_sync_not_recreate_trashed_field_property_on_sync(data_fixture):
responses.add(
responses.GET,
"https://baserow.io/ical.ics",
status=200,
body=ICAL_FEED_WITH_TWO_ITEMS,
)
user = data_fixture.create_user()
database = data_fixture.create_database_application(user=user)
handler = DataSyncHandler()
data_sync = handler.create_data_sync_table(
user=user,
database=database,
table_name="Test",
type_name="ical_calendar",
synced_properties=["uid", "dtstart"],
ical_url="https://baserow.io/ical.ics",
)
fields = specific_iterator(data_sync.table.field_set.all().order_by("id"))
FieldHandler().delete_field(user, fields[1])
data_sync = handler.sync_data_sync_table(user=user, data_sync=data_sync)
assert Field.objects_and_trash.filter(table=data_sync.table).count() == 2
@pytest.mark.field_duration
@pytest.mark.django_db
@responses.activate

View file

@ -0,0 +1,7 @@
{
"type": "bug",
"message": "Fix error when syncing a table with a trashed field.",
"issue_number": null,
"bullet_points": [],
"created_at": "2025-02-12"
}

View file

@ -297,7 +297,7 @@ class LocalBaserowTableDataSyncType(DataSyncType):
enabled_properties = DataSyncSyncedProperty.objects.filter(
data_sync=instance
).prefetch_related(
Prefetch("field", queryset=specific_queryset(Field.objects.all()))
Prefetch("field", queryset=specific_queryset(Field.objects_and_trash.all()))
)
enabled_property_field_ids = [p.key for p in enabled_properties]
model = table.get_model()

View file

@ -13,6 +13,7 @@ from rest_framework.status import (
from baserow.contrib.database.data_sync.exceptions import SyncError
from baserow.contrib.database.data_sync.handler import DataSyncHandler
from baserow.contrib.database.fields.handler import FieldHandler
from baserow.contrib.database.fields.models import NumberField
from baserow.contrib.database.fields.registries import field_type_registry
from baserow.contrib.database.table.handler import TableHandler
@ -1584,3 +1585,38 @@ def test_source_table_view_deleted(enterprise_data_fixture):
# We expect the view to still exist so that it fails because if it's set to
# `null`, it might expose all table data.
assert data_sync.source_table_view_id == grid_id
@pytest.mark.django_db
@override_settings(DEBUG=True)
def test_table_with_trashed_synced_field(enterprise_data_fixture):
enterprise_data_fixture.enable_enterprise()
user = enterprise_data_fixture.create_user()
source_table = enterprise_data_fixture.create_database_table(
user=user, name="Source"
)
source_text_field = enterprise_data_fixture.create_text_field(table=source_table)
source_table.get_model().objects.create()
database = enterprise_data_fixture.create_database_application(user=user)
handler = DataSyncHandler()
data_sync = handler.create_data_sync_table(
user=user,
database=database,
table_name="Test",
type_name="local_baserow_table",
synced_properties=["id", f"field_{source_text_field.id}"],
source_table_id=source_table.id,
)
handler.sync_data_sync_table(user=user, data_sync=data_sync)
fields = specific_iterator(data_sync.table.field_set.all().order_by("id"))
FieldHandler().delete_field(user, fields[1])
handler.sync_data_sync_table(user=user, data_sync=data_sync)
data_sync.refresh_from_db()
assert data_sync.last_error is None