Separate databases and SAAS in general

Although I don’t currently have a customer need for it, I’d like to know if it’s possible for each customer to have their own database in my Anvil app? Is it just a matter of selecting the correct Anvil plan (which I just quickly reviewed but didn’t see), or is it a technical limitation? My Anvil app is currently storing all customer data in one database. I also just noticed that I can’t add a second DataTables service to my app.

Also, would it be possible to have a new forum category called something like “Running Your SaaS” where developers can discuss more of the business side of running a Anvil-based SaaS application?

With the hosted versions of Anvil (ie most of the plans) no, you have only one database. I don’t know if the dedicated plans allow it or not (as I know it gives you full SQL access).

I use external databases which allows you full freedom (and each of my customers have their own DB).

You could make your Data Tables multi-tenant by having a customer table and making all subsequent data for each customer linked to the one row in that table. It’s a logical separation but it should work fine.

David, that’s what I’m currently doing and it works fine. I recently read a SaaS-related article, that due to the nature of the developer’s SaaS and its customers, the developer was forced to go from a single DB to separate DBs for each customer, something he hadn’t accounted for during development (because it never occurred to him) and proved for him to be a difficult re-engineering effort.

Been there :slight_smile: hence why I use external databases myself. Sometimes I’m forced to shift platforms or fit in (retrospectively) with other systems. I’d rather use Data Tables (and I wish I could plug in the API to external servers) but hey ho.

If you’d like to future-proof yourself against the, ahem, possibility that this gets added to Data Tables (:wink:), here’s a pattern you can use: Make a view of a table restricted to one tenant, and use that view instead of the table.

This works because you can use views just like tables - you can call add_row(), search() etc on them. To learn more about Data Table views, check out this video tutorial, or the Data Tables docs.

Here’s some example code:

def get_table_for_tenant(name):
  tenant = app_tables.tenants.get(name=name)
  if tenant is None:
    raise Exception('No such tenant: ' + repr(name))
  return app_tables.my_table.client_readable(tenant=tenant)

@anvil.server.callable
def mk_new_record(...):
  # instead of:
  # return app_tables.foo.add_row(...)
  # you can do:
  my_tbl = get_table_for_tenant(CURRENT_TENANT)
  return my_tbl.add_row(...)

(You can do all sorts of clever things, like storing the tenant identity and table views in anvil.server.session once so you don’t have to look them up after that, etc.)

If you write your apps like this, you’ll be well prepared if you do need to separate out tenants into separate tables – you’d only have to swap out the implementation of get_table_for_tenant().

If you eventually need even stricter separation (eg putting those tables into different Postgres instances), then if this feature isn’t available by the time you want it, you’d probably have enough revenue to take out a support contract and commission it!

If you’d like to talk about commissioning features and other benefits of a support contract, drop us a line at support@anvil.works!

3 Likes

The truth is I don’t think I have looked at Data Tables in the detail that I probably should have, preferring to fall back to what I know.

I shall do that over the next few days and see where that leads me :slight_smile:

1 Like

A post was split to a new topic: Client writable cascade