django.core.exceptions.FieldDoesNotExist despite running migration

I’m adding a new FieldType, and following this tutorial:
https://baserow.io/docs/plugins%2Ffield-type
I’ve added the field type, the model, and have run

./dev.sh run backend manage makemigrations
./dev.sh run backend manage migrate

despite that, I get the error below when attempting to add the field from a table using the frontend. I’m going to dig into this further but I was wondering anything looked obvious to the django experts here.

You can see my diffs against the master baserow repo here: Comparing master...20220611_language_field_type · Language-Tools/vocab-ai · GitHub

ERROR 2022-06-11 13:32:15,046 django.request.log_response:230- Internal Server Error: /api/database/fields/table/260/
Traceback (most recent call last):
  File "/baserow/venv/lib/python3.7/site-packages/django/db/models/options.py", line 608, in get_field
    return self.fields_map[field_name]
KeyError: 'field_2021'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/baserow/venv/lib/python3.7/site-packages/asgiref/sync.py", line 482, in thread_handler
    raise exc_info[1]
  File "/baserow/venv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 38, in inner
    response = await get_response(request)
  File "/baserow/venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 233, in _get_response_async
    response = await wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/baserow/venv/lib/python3.7/site-packages/asgiref/sync.py", line 444, in __call__
    ret = await asyncio.wait_for(future, timeout=None)
  File "/usr/lib/python3.7/asyncio/tasks.py", line 388, in wait_for
    return await fut
  File "/baserow/venv/lib/python3.7/site-packages/asgiref/current_thread_executor.py", line 22, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/baserow/venv/lib/python3.7/site-packages/asgiref/sync.py", line 486, in thread_handler
    return func(*args, **kwargs)
  File "/baserow/venv/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/baserow/venv/lib/python3.7/site-packages/django/views/generic/base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "/baserow/venv/lib/python3.7/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/baserow/venv/lib/python3.7/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/baserow/venv/lib/python3.7/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/baserow/venv/lib/python3.7/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/usr/lib/python3.7/contextlib.py", line 74, in inner
    return func(*args, **kwds)
  File "/baserow/backend/src/baserow/api/decorators.py", line 261, in func_wrapper
    return func(*args, **kwargs)
  File "/baserow/backend/src/baserow/api/decorators.py", line 83, in func_wrapper
    return func(*args, **kwargs)
  File "/baserow/backend/src/baserow/contrib/database/api/fields/views.py", line 226, in post
    ).do(request.user, table, type_name, return_updated_fields=True, **data)
  File "/baserow/backend/src/baserow/contrib/database/fields/actions.py", line 599, in do
    **kwargs,
  File "/baserow/backend/src/baserow/contrib/database/fields/handler.py", line 266, in create_field
    model_field = to_model._meta.get_field(instance.db_column)
  File "/baserow/venv/lib/python3.7/site-packages/django/db/models/options.py", line 610, in get_field
    raise FieldDoesNotExist("%s has no field named '%s'" % (self.object_name, field_name))
django.core.exceptions.FieldDoesNotExist: Table260Model has no field named 'field_2021'
ERROR 2022-06-11 13:32:15,046 django.request.log_response:230- Internal Server Error: /api/database/fields/table/260/
Traceback (most recent call last):
  File "/baserow/venv/lib/python3.7/site-packages/django/db/models/options.py", line 608, in get_field
    return self.fields_map[field_name]
KeyError: 'field_2021'

Have you registered the field in the registry?

I did, like this:

field_type_registry.register(TranslationFieldType())
not sure whether this is sufficient or whether something else is needed
you can see all my diffs against master baserow here by the way: Comparing master...20220611_language_field_type · Language-Tools/vocab-ai · GitHub

@lucw your

    def get_model_field(self, instance, **kwargs):
        return TranslationField

is incorrect. This needs to return a Django Model Field instance. For your field type I imagine this would be a TextField like so:

    def get_model_field(self, instance, **kwargs):
        return models.TextField(
             blank=True, null=True, **kwargs
        )
1 Like

Amazing !! Making progress now. I need to sort out the front-end component now.
Huge thanks for taking the time to review my diffs and identify the issue @nigel
as a Django novice i’m still very much of my depth, but I expect to get there soon.

No worries, FYI our usage of Django internally can get quite non-standard so feel free to ask any questions you might have :slight_smile: Also see this blog post where Bram goes into more detail about our custom usage of models in Baserow: How Baserow lets users generate Django models on the fly // Baserow

Also I kept on meaning to mention, the plugin boilerplate on my MR in gitlab is still a work in progress and more changes will be made soon on it. Apologizies for any inconvenience caused by the plugin stuff changing under your feet. When the merge request is ready and if your plugin follows the correct folder structure you should be able to install it into any Baserow instance downloading the plugin straight from github by issuing a command (after 1.11 is released). There will be hopefully clear docs on how to structure this new type of Baserow plugin once it is ready also.

Hey @lucw

Just an FYI in 1.10.2 we released a rework of our plugin system which should mean packaging, publishing and installing any plugin you make is much easier now! Checkout Introduction // Baserow for more details, let me know if theres anything else I can do to help :slight_smile:

Thank you, i’ll be looking into this shortly. I was able to develop the functionality that I need, and if adapting to this new plugin framework allows me to pull-in baserow updates more easily then it’ll be a great benefit.

1 Like

For the record, looks like I was able to update my fork from 1.10 to 1.11 with minimal changes @nigel . I saw the work you did on improving the field dependency code, it only required minor changes and I was able to get up and running.
The changes for my project have been extensive, requiring a new celery worker, some changes to docker files, things like that. I don’t know whether this precludes packaging my changes into a plugin or not. I’ll explain everything when I take you up on your offer for a code review maybe in the coming weeks.

@nigel I can confirm I’m able to bring up baserow using the tutorial here: Boilerplate // Baserow and i’ll look into converting my fork to the plugin format. I realized that with a fork, i’d have to do quite a bit of work to build customized docker images, while as the plugin framework seems to be designed specifically for that.
I’ll keep you updated on my progress but so far my experience is positive.

1 Like

Great to hear :slight_smile: Still some rough edges I bet but we hope to publish some official plugins soon and start the ball rolling on smoothing them out.

I was able to upgrade my plugin to baserow 1.12.0 in a few minutes. So i’m already seeing the benefits of using plugins. Many thanks for designing such an extensible system !

1 Like