<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Knowledge Base (Posts about contentdb)</title><link>https://bgstack15.ddns.net/blog/</link><description></description><atom:link href="https://bgstack15.ddns.net/blog/categories/contentdb.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2026 &lt;a href="mailto:bgstack15@gmail.com"&gt;bgstack15&lt;/a&gt; 
&lt;a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.html"&gt;
&lt;img alt="GNU General Public License v3.0"
style="border-width:0; margin-bottom:12px;"
src="https://bgstack15.ddns.net/.images/gplv3-127x51.png"&gt;&lt;/a&gt;</copyright><lastBuildDate>Sun, 10 May 2026 13:01:22 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Upgrading contentdb narrative</title><link>https://bgstack15.ddns.net/blog/posts/2026/05/10/upgrading-contentdb-narrative/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I run an &lt;a href="http://vm4:5123"&gt;Internal ContentDB&lt;/a&gt; for &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/luanti.org"&gt;Luanti&lt;/a&gt; users. I know the &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org"&gt;upstream ContentDB&lt;/a&gt; receives updates to its &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/luanti-org/contentdb"&gt;code&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2026/scrot-contentdb.png"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/scrot-contentdb-small.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;The code uses python3, &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/flask.palletsprojects.com/en/stable/"&gt;flask&lt;/a&gt;, and &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/flask.palletsprojects.com/en/stable/patterns/sqlalchemy/"&gt;SqlAlchemy&lt;/a&gt;. 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.&lt;/p&gt;
&lt;h2&gt;The actions&lt;/h2&gt;
&lt;p&gt;In a containerized application, you normally run &lt;code&gt;docker pull &amp;lt;imagename&amp;gt;&lt;/code&gt;, but there aren't pre-built images for this project. But it's not hard to run &lt;code&gt;docker build .&lt;/code&gt; to build it yourself. So I did that, and then tried restarting the container, and it failed.&lt;/p&gt;
&lt;p&gt;I failed to keep the exact error messages, but it boiled down to a "circular dependency problem."&lt;/p&gt;
&lt;p&gt;I then connected to the running container to manually run alembic commands to upgrade the database. You can see the &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/luanti-org/contentdb/tree/master/migrations/versions"&gt;changes to the database schema&lt;/a&gt;. I've never used alembic directly before; I've always used &lt;code&gt;flask db upgrade&lt;/code&gt;, and I eventually figured how to do that in &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/luanti-org/contentdb/blob/master/utils/run_migrations.sh"&gt;this containerized fashion&lt;/a&gt;. 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 &lt;code&gt;flask db upgrade&lt;/code&gt; is a better and simpler way.&lt;/p&gt;
&lt;p&gt;So the database could get upgraded, but I still cannot run the flask app because of the circular dependency problem. &lt;code&gt;utils&lt;/code&gt; kept trying to import &lt;code&gt;app.utils&lt;/code&gt; or vice versa. This was the real problem of my upgrade, which was solved after I looked through the code history and found &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/luanti-org/contentdb/commit/fa3697a7bdb89c15bab9551ebdc64bdf1d95be39"&gt;Commit &lt;code&gt;fa3697a&lt;/code&gt;: &lt;code&gt;Split up app/utils/__init__.py to reduce issues&lt;/code&gt;&lt;/a&gt;. The problem still happens though, because of how the container loads the app from a mounted volume, into the location where it will run.&lt;/p&gt;
&lt;p&gt;That file, &lt;code&gt;app/utils/__init__.py&lt;/code&gt;, 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 &lt;code&gt;--delete-after&lt;/code&gt; parameter. Therefore, I had to go into the container and delete &lt;code&gt;app/utils/__init__.py&lt;/code&gt;. Then I could run that &lt;code&gt;flask db upgrade&lt;/code&gt; from the utility script, and then start up the application.&lt;/p&gt;
&lt;p&gt;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 &lt;code&gt;utils&lt;/code&gt; cannot import &lt;code&gt;app.utils&lt;/code&gt;, and vice versa. So I'm glad the ContentDB team rewrote it so one of them no longer has a module (&lt;code&gt;__init__.py&lt;/code&gt;) directly, to choke.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;</description><category>contentdb</category><category>luanti</category><category>narrative</category><category>troubleshooting</category><category>web</category><guid>https://bgstack15.ddns.net/blog/posts/2026/05/10/upgrading-contentdb-narrative/</guid><pubDate>Sun, 10 May 2026 12:55:00 GMT</pubDate></item></channel></rss>