Background task -->anvil.tables.TableError: Internal database error: ERROR: canceling statement due to user request

What I’m trying to do:
Write in data table using background task. There was no problem with the function until yesterday, and I had not changed any code related to this background task.


proj = app_tables.projects.get(project_name=pro)
if proj:
      proj.update(data=data)

anvil.tables.TableError: Internal database error: ERROR: canceling statement due to user request
App session = MAHDFJWVFDSVWQ7P5TRG4DZ6AXTQXCG7

Hi @clinical,

That usually means your request has timed out – which might have something to do with the huge amount of data currently being fetched by your app, especially in Accelerated Tables mode which now fetches all SimpleObjects and follows links by request. If I had to guess, the payload of that get() response is so large it’s causing a timeout. (Improving that error message is definitely on us!)

The simplest fix here is probably to fetch a bit less data, by passing q.fetch_only() to the get() method. The bigger fix is to look at how much data you’re storing in each table row, and see if you can spread it out a bit (ie if you’re storing many megabytes of related data for each row in Simple Objects, which isn’t needed for every query, you might want to start using more rows in linked tables to model those entities instead).

2 Likes

Thank you! @meredydd, I’ll definitely explore these optimizations further.
Just to clarify, you’re indicating that the accelerated tables are returning more data compared to regular tables, which may be the source of the frequent timeout errors I’m experiencing? This explains why I did not experience any issues with the same code in the past.

Disregard this :point_down:

Also, regarding this error, I am updating a row;

would that considered fetching as well?

It turn out that there is another part of the code going very slow (still investigating :man_detective:) and causing multiple similar background task calls interfering with each other when they trying to update the same row :person_facepalming:.

The following code prevented the canceling statement error

def check_and_abort_task(n_task):
    current_tasks = anvil.server.list_background_tasks()
    for task in current_tasks:
        if task.get_task_name() == n_task.get_task_name() and task.is_running():
            task.kill()
            print(1645,f"Task {task_name} is already running. Aborting new task.")

I am not sure if there is a better way to stop the task before launching it :thinking:

task.is_running() very frequently does not work as expected all the time, its much more reliable to use
task.get_return_value() is None

Unless you have a return value that might be None, obviously that would never evaluate to True

3 Likes

Thank you for the tip @ianbuywise :+1:.