Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

Upgrading contentdb narrative

I run an Internal ContentDB for Luanti users. I know the upstream ContentDB receives updates to its code.

I was months and months behind the upstream codebase, so I decided to try to upgrade my code. The most visible feature that I could use to confirm I had a new version is the display of "AI disclosure" on a package.

The code uses python3, flask, and SqlAlchemy. I've used all these technologies before, but not as deeply as the ContentDB team! It does make me happy that I have approximately the same skillset as that team.

The actions

In a containerized application, you normally run docker pull <imagename>, but there aren't pre-built images for this project. But it's not hard to run docker build . to build it yourself. So I did that, and then tried restarting the container, and it failed.

I failed to keep the exact error messages, but it boiled down to a "circular dependency problem."

I then connected to the running container to manually run alembic commands to upgrade the database. You can see the changes to the database schema. I've never used alembic directly before; I've always used flask db upgrade, and I eventually figured how to do that in this containerized fashion. But I had learned a lot about what I needed to add to the alembic configs so it could find its components. They're scribbled somewhere, but I'm not going to look for them because the flask db upgrade is a better and simpler way.

So the database could get upgraded, but I still cannot run the flask app because of the circular dependency problem. utils kept trying to import app.utils or vice versa. This was the real problem of my upgrade, which was solved after I looked through the code history and found Commit fa3697a: Split up app/utils/__init__.py to reduce issues. The problem still happens though, because of how the container loads the app from a mounted volume, into the location where it will run.

That file, app/utils/__init__.py, was deleted, but when the container startup script copies all files in, it doesn't remove files. It's one of those classic computer science problems, where it won't clean up a deleted file. It doesn't know that file exists, and doesn't care. It's not rsync with a --delete-after parameter. Therefore, I had to go into the container and delete app/utils/__init__.py. Then I could run that flask db upgrade from the utility script, and then start up the application.

The reason that file was deleted, was because you cannot have a python module import another module of the same name. That means directory name, even if it's a different directory. So utils cannot import app.utils, and vice versa. So I'm glad the ContentDB team rewrote it so one of them no longer has a module (__init__.py) directly, to choke.

And now for some reason, every time I restart the container, I have to re-run the flask db upgrade step. That's weird, but I can live with it.

Comments