diff --git a/.gitignore b/.gitignore index 3ef1fa69f..a648828b3 100644 --- a/.gitignore +++ b/.gitignore @@ -123,6 +123,9 @@ out/ .cursor-config/ !config/cursor/.cursor-config/ +# Pyright config file +pyrightconfig.json + # VIM's swap files *.swp @@ -146,4 +149,4 @@ premium/web-frontend/package.json # Storybook web-frontend/.nuxt-storybook/ -web-frontend/storybook-static \ No newline at end of file +web-frontend/storybook-static diff --git a/backend/src/baserow/contrib/database/rows/handler.py b/backend/src/baserow/contrib/database/rows/handler.py index 1c91cb225..87786902b 100644 --- a/backend/src/baserow/contrib/database/rows/handler.py +++ b/backend/src/baserow/contrib/database/rows/handler.py @@ -1875,7 +1875,7 @@ class RowHandler(metaclass=baserow_trace_methods(tracer)): if ( not isinstance(model_field, ManyToManyField) and field_id in updated_field_ids - and field_type.valid_for_bulk_update(model_field) + and field_type.valid_for_bulk_update(field_obj["field"]) ): bulk_update_fields.append(field_name) diff --git a/changelog/entries/unreleased/bug/3403_fix_for_data_sync_fails_when_syncing_baserow_table_with_aifi.json b/changelog/entries/unreleased/bug/3403_fix_for_data_sync_fails_when_syncing_baserow_table_with_aifi.json new file mode 100644 index 000000000..f4b27223c --- /dev/null +++ b/changelog/entries/unreleased/bug/3403_fix_for_data_sync_fails_when_syncing_baserow_table_with_aifi.json @@ -0,0 +1,8 @@ +{ + "type": "bug", + "message": "Fix for data sync failing when syncing baserow table with AIField", + "domain": "database", + "issue_number": 3403, + "bullet_points": [], + "created_at": "2025-03-12" +} \ No newline at end of file diff --git a/enterprise/backend/tests/baserow_enterprise_tests/data_sync/test_data_sync_ai_field.py b/enterprise/backend/tests/baserow_enterprise_tests/data_sync/test_data_sync_ai_field.py new file mode 100644 index 000000000..0df8a8bb7 --- /dev/null +++ b/enterprise/backend/tests/baserow_enterprise_tests/data_sync/test_data_sync_ai_field.py @@ -0,0 +1,61 @@ +from django.test.utils import override_settings + +import pytest + +from baserow.contrib.database.data_sync.handler import DataSyncHandler + + +@pytest.mark.django_db +@override_settings(DEBUG=True) +def test_sync_table_with_ai_field(enterprise_data_fixture, premium_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" + ) + field_1 = enterprise_data_fixture.create_text_field( + table=source_table, name="Text", primary=True + ) + ai_field = premium_data_fixture.create_ai_field( + table=source_table, + name="ai_field", + ai_generative_ai_type="test_generative_ai", + ai_generative_ai_model="test_1", + ai_prompt="field('text_field')", + ) + source_model = source_table.get_model() + source_row_1 = source_model.objects.create( + **{ + f"field_{field_1.id}": "Text field", + f"field_{ai_field.id}": "AI Field value #1", + } + ) + + 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_{field_1.id}", f"field_{ai_field.id}"], + source_table_id=source_table.id, + ) + handler.sync_data_sync_table(user=user, data_sync=data_sync) + + source_row_1.refresh_from_db() + + # We don't need AI calculations for this test. We just need value changed to + # trigger the sync. + setattr(source_row_1, f"field_{ai_field.id}", "AI Field value #2") + source_row_1.save() + + handler.sync_data_sync_table(user=user, data_sync=data_sync) + + source_row_1.refresh_from_db() + + assert data_sync.last_sync is not None + assert data_sync.last_error is None