Storing media in data tables (was Unexpected: Server code took too long)

As part of one my apps I need to upload a spreadsheet, parse it (yay pandas) and insert a bunch of rows into my data tables. It’s a big job - the spreadsheet has maybe 50 columns and over 1000 lines (a large number of which are empty, but need to be checked).

While I’m very open to some help to make this more efficient, I think it’s fundamentally going to take a while and I was wondering if there’s anything I can do about the error that I get:

unexpected: Server code took too long

Hi there,

Is this part of your app’s normal day-to-day operation, or is this a one-time import of data? If it’s a one-time import, I would suggest running the import job on an Uplink, which isn’t time-restricted because it runs on your hardware. (See here for a code example: Importing existing data into Data Table)

If it’s part of your day-to-day operation, you have two options. As a business customer we can raise the timeout on your code (so it can complete all at once) - this makes sense if it you only need a little extra time (eg the import will only take a minute or two). Otherwise, we’d recommend doing it in chunks - eg store the file itself in a Data Table row, and make one server call that only imports lines 0-99, one server call that imports lines 100-199, and so on. (The advantage here is that you can give your client a progress indication too.)

Does that make sense to you?

It’s something that users are going to need to do weekly, so will need to be done client side. Looking at how far it’s got, we’d have to raise the timeout significantly, which could have other impacts. So I guess it’s the last option. I was thinking about progress bars anyway.

How would you store the file in a data table row?

If you go to add a column to a data table, you will see the option to add a Media column. This can hold any Anvil Media object - such as the file you get from a FileLoader. Eg the following works, assuming you have a data table called uploaded_files with a Media column called f:

  # On the client
  def fileloader_1_change(self, **params):
    anvil.server.call('save_file', self.file_loader_1.file)
# On the server
@anvil.server.callable
def save_file(file):
  app_tables.uploaded_files.add_row(f = file)

Bonus note:
It’s also easy to make media from data tables downloadable. Just get the url property of the Media object and set it as the URL of a Link component. This will get you a private download link for that file, which only works in that browser session. Eg:

  # On client
  def setup_download_link(self):
    # Get the first row from the uploaded_files table:
    r = app_tables.uploaded_files.search()[0]
    self.download_link.url = r['f'].url
    # Now you can download that file by clicking download_link
1 Like

Is there anyway to “click the link” from code? I have a button which finds the file and sets the url of a link to the file path. But I’d rather not make my users click again if possible.

This is useful.
I’ve added a link in a repeating panel row
a) I did databinding and bind it to url property

self.item['Picture']

but when I run the app and click on the link nothing happens.
What I need to do when you click on the button that photo is downloaded?

b) Do I need to do it in click event?

 def link_1_click (self, **event_args):
    # This method is called when the link is clicked
    self.item['Picture'].url
    #or I need to?: "return self.item['Picture'].url"
    pass

c) How do I make the link hidden if there is no picture in that row?

Thanks
Lucas

Aha - you need to bind it to the Media object’s url attribute (eg self.item['Picture'].url).

But you should be able to bind the url property directly to a Media object. That would make sense, and it’s a perfectly logical thing you tried to do. So we’ve added it to our TODO list!

(No, you don’t need a click event. As a rule of thumb, for a Link element, you usually want either a url to go to, or a click event, but not both.)

This seems awesome I really like the fact that files are protected within that session as well. One thing though, what are the file size limits for storing files in the DB (per file and also total used space).