Unintended sharing of Users table between Environments -- how to fix?

Continuing the discussion from In Uplink, is it safe to reset anvil.tables.AppTables.cache between connections? Is there a better way?:

What I’m trying to do:
My App has DevTest data, in its Default Database, accessible from a couple of Environments. I want to copy some “bootstrap” data from that database to its other database named Public, accessible from an environment named Published.

The “bootstrap” data defines the database’s first, “prototype” user, including attached records that define default values for all new users. It has to be there. Without it, the post-login app-startup sequence will crash.

What I’ve tried and what’s not working:

  1. I’ve successfully created database Public, as a clone of the Default Database. All tables were created empty.
    Table Members was set, in the Default Database, as the users table, ages ago. As you can see, its clone is set to be read-writable from Server-side code.

  2. I’ve told Environment Published that it is to use database Public:
    image
    So it should be using Public’s table Members instead.

  3. This is brand-new code, writing many records, starting with the root of this hierarchy, the new (1st) user, so it’s likely to fail somewhere along the line, leaving partial results in the database. Thus, in case I’ve already succeeded in creating that user, I query table Members. This naturally returns None. Public.Members is empty. Then, to create this first user, I have a call to anvil.users.signup_with_email().

It is at this specific point that I get the dreaded message,

This table cannot be written or searched by this app

Code Sample:

new_user = anvil.users.signup_with_email(email_address, password)

It’s as if Environment Published is trying to use the wrong table.

Is there some setting that I’m missing?

Edit (2022-11-23): This may be a clue: All 3 of my anvil.yaml files have

server_config: {user_table: 61863}

(I have one file each, for the branches used by Development, Testing, and Published.)
This suggests that anvil.users is, indeed, sharing the same Members table among all of the Environments.

What do I have to do to get Published to use its own Members table?

I tried a dangerous hack:

  1. Download (as CSV) Default Database Members table. All row ids begin with 61863. This does appear to identify the table.
  2. Add a (temporary) dummy record to Public Members table, so that there would be a row with a row id, and download it as CSV. This gives me the id of this table.
  3. Modify the anvil.yaml entry in branch “published”, to use this new table id, in place of the original one, and use Git to push that update into Anvil’s copy of that branch.
  4. Verify the results in the Beta IDE.

Formerly, the old Default Database Members table would show in the Users Service, no matter which branch I had selected. Now, when in the Published branch, it correctly shows the contents of the Public Members table. And I am able, finally, to create new users in the Public Members table via anvil.users.signup_with_email().

Note that the Users Service shows in its own IDE tab. This tab does NOT refresh when you change branches. To accurately see the Users Service settings for a branch, you must close its tab, then switch branches, and reopen the Service. This will force the tab contents to be re-generated.

I do not recommend this kind of hack to anyone. It depends on assumptions that are subject to change at any time.

Edit:
I’m getting some puzzling results. Need to step back and try to find a pattern.

Hi @p.colbert,

Looks like you’re hitting an odd edge case! - sorry for the frustrating experience! This is happening because you set up your Users Service before we switched to identifying the user table by name.

If you’re already hacking your YAML around, you can fix this pretty simply by changing {user_table: 61863} to {user_table: "users"}. That way your apps will start resolving the users table by name, and refer to the correct table in whatever environment it’s running in.

More crudely, you could also remove and re-add the Users Service to your app, which will reinitialise it all modern-style :slight_smile:

1 Like

Seems like a straightforward and elegant solution. Thanks! I’m trying this out now.

Edit: It seems to be working as expected. Thank you so much!!!

For my understanding:
Although each source-code branch appears to have its own anvil.yaml file, I’m guessing that this particular setting is common across all of them. At least, that’s what happened when I used a numeric table identifier. Change it in one, and the others changed to match.

If so, then if one branch uses a table named “members”, then all branches (of the same app) must use the same name.

Is that correct?