Trouble updating for the first time from 0.15.7 to 0.15.8

We are running Ubuntu and re just upgraded from 0.15.7 to 0.15.8 for the first time. When starting we receive the following error:

.kolibri$ vi options.ini
cw-kolibri@ip-10-0-1-179:~/.kolibri$ kolibri start
INFO: No C extensions are available for this platform
INFO     2022-10-21 15:03:30,430 Option DEBUG in section [Server] being overridden by environment variable KOLIBRI_DEBUG
INFO     2022-10-21 15:03:30,430 Option DEBUG_LOG_DATABASE in section [Server] being overridden by environment variable KOLIBRI_DEBUG_LOG_DATABASE
/usr/lib/python3/dist-packages/kolibri/dist/rest_framework/utils/serializer_helpers.py:107: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if value is None or value is '':
INFO     2022-10-21 15:03:30,978 Running Kolibri with the following settings: kolibri.deployment.default.settings.base
WARNING  2022-10-21 15:03:31,033 Unable to check Redis settings
WARNING  2022-10-21 15:03:31,034 unknown command `CONFIG`, with args beginning with: `GET`, `maxmemory-policy`,
WARNING  2022-10-21 15:03:31,136 Skipped automatic database backup, not compatible with this DB engine.
INFO     2022-10-21 15:03:31,136 Version was 0.15.7, new version: 0.15.8
INFO     2022-10-21 15:03:31,136 Running update routines for new version...
Operations to perform:
  Apply all migrations: admin, analytics, auth, bookmarks, content, contenttypes, device, discovery, exams, kolibriauth, lessons, logger, morango, notifications, sessions
Running migrations:
  Applying kolibriauth.0001_initial...Error: Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/kolibri/dist/django/db/backends/utils.py", line 62, in execute
    return self.cursor.execute(sql)
psycopg2.errors.DuplicateTable: relation "kolibriauth_collection" already exists

So my thought on this stems from the fact that we are using Postgres as a backend. When configuring this we loaded every .sqlite3 file into the database as there is really little doc as to properly running Postgres. This may not be the case. That being said, I can confirm that this table does indeed exist. There is one entry in there.

How should we proceed with things so that we can start Kolibri?

hi @Brian_LePore it looks like you’re running the migrations over a database that had them already in place.
I see a weird error message about an unknown CONFIG option that you seem to have added to your options.ini file. It would be good to know the contents of that file, as it seems you’re mixing postgresql and sqlite configs.

Looking at your logs, the system has recognized you’re migrating from 0.15.7 to 0.15.8, so it should be skipping most of the database migrations, if it’s not doing it, it’s a symptom of a wrong content in the django_migrations table of the database it’s connecting.

Hope it helps
José

Hi there.

So our options.ini looks like:

[Cache]
# Which backend to use for the main cache - if 'memory' is selected, then for most cache operations,
# an in-memory, process-local cache will be used, but a disk based cache will be used for some data
# that needs to be persistent across processes. If 'redis' is used, it is used for all caches.
#CACHE_BACKEND = memory
CACHE_BACKEND = redis

# Default timeout for entries put into the cache.
# CACHE_TIMEOUT = 300
CACHE_TIMEOUT = 300

# Maximum number of entries to maintain in the cache at once.
# CACHE_MAX_ENTRIES = 1000
CACHE_MAX_ENTRIES = 1000

# Password to authenticate to Redis, Redis only.
# CACHE_PASSWORD =
CACHE_PASSWORD =

# Host and port at which to connect to Redis, Redis only.
# CACHE_LOCATION = localhost:6379
CACHE_LOCATION = rediss://REDACTED:6379
# YOU MUST MANUALLY IMPORT THIS MERGED FIX FOR STUFF TO WORK
# https://github.com/sebleier/django-redis-cache/pull/170/commits/934187328c1c27e020b3c0d331701889cc6dee84
# /usr/lib/python3/dist-packages/kolibri/dist/redis_cache/connection.py
# /usr/lib/python3/dist-packages/kolibri/dist/redis_cache/utils.py


# The database number for Redis.
# CACHE_REDIS_DB = 0
CACHE_REDIS_DB = 0

# Maximum number of simultaneous connections to allow to Redis, Redis only.
# CACHE_REDIS_MAX_POOL_SIZE = 50
CACHE_REDIS_MAX_POOL_SIZE = 50

# How long to wait when trying to connect to Redis before timing out, Redis only.
# CACHE_REDIS_POOL_TIMEOUT = 30
CACHE_REDIS_POOL_TIMEOUT = 30

# Maximum memory that Redis should use, Redis only.
# CACHE_REDIS_MAXMEMORY = 0
# 10 GB
CACHE_REDIS_MAXMEMORY = 10737418240

# Eviction policy to use when using Redis for caching, Redis only.
# CACHE_REDIS_MAXMEMORY_POLICY =
CACHE_REDIS_MAXMEMORY_POLICY =

[Database]
# Which database backend to use, choices are 'sqlite' or 'postgres'
DATABASE_ENGINE = postgres

# For SQLite - the name of a database file to use for the main Kolibri database.
# For Postgresql, the name of the database to use for all Kolibri data.
DATABASE_NAME = kolibri

# The password to authenticate with when connecting to the database, Postgresql only.
DATABASE_PASSWORD = REDACTED

# The user to authenticate with when connecting to the database, Postgresql only.
DATABASE_USER = REDACTED

# The host on which to connect to the database, Postgresql only.
DATABASE_HOST = REDACTED

# The port on which to connect to the database, Postgresql only.
DATABASE_PORT = 5432

[Server]
DEBUG = False
DEBUG_LOG_DATABASE = False
# How many threads the Kolibri server should use to serve requests
# CHERRYPY_THREAD_POOL = 50

# How many seconds to wait for a request to be put into the queue.
# Increasing this may help situations where requests are instantly refused by the server.
# CHERRYPY_QUEUE_TIMEOUT = 0.1

# Activate the server profiling middleware.
# PROFILE = False

# Run Kolibri with Django setting DEBUG = True
# DEBUG = False

# Activate debug logging for Django ORM operations.
# DEBUG_LOG_DATABASE = False

[Paths]
# The directory that will store content files and content database files.
# To change this in a currently active server it is recommended to use the
# 'content movedirectory' management command.
CONTENT_DIR = REDACTED

# Additional directories in which Kolibri will look for content files and content database files.
# CONTENT_FALLBACK_DIRS =

The rest of the file is the standard options.ini which have been commented out.

Honestly, we had a lot of issues when switching from sqlite to postgres. I had to manually update a bunch of tables to add columns onto them. I’m not sure what that was all about.

What would I need to change in django_migrations?

The django_migrations table should contain all the migrations that had previously run, so it does not try to create again tables that already existed (that’s the error message you saw). You should have the same info in this table that you had in your original database (for you to have an aproximate idea, looking at my server I have 136 rows there, with all the migrations that have previously run).
I guess you didn’t update this table when you did the manual update.

Appart from t hat, your options.ini file seems fine, excepting in the
CACHE_REDIS_MAXMEMORY_POLICY =
section. Please, change it to
CACHE_REDIS_MAXMEMORY_POLICY = allkeys-lru
to avoid the config error (it’s not critical but it’ll affect to your performance if you don’t do it)

José

So I applied that change and tried to restart, but it still has the maxmemory-policy line. Could this have anything to do with my recent custom django file to set the cache in such a way to connect to Redis over TLS?

Additionally, I’m not sure why, but I only have three entries in my django_migrations folder.

pgAdmin 4

To be clear, I started with 0.15.7 as my initial install. My process was:

  1. Normal install using SQL lite.
  2. Use pgloader to move all of the sqllite folders into a Postgres db.
  3. Change the config to use Postrgres.
  4. Install all the channels I would like.
  5. Moved all of the content to a network file system. Believe I needed to manually use pgloader to import the sqllite files again, I forget.
  6. Make the config changes to use Redis as detailed in the other post.

During the content loading phase, I did need to eventually start importing content along the command line. When doing that I needed to alter tables by hand a number of times based on errors.

hi @Brian_LePore , for the maxmemory-policy I am not sure, I’d need to check that change you did in deep. In any case, kolibri will start with it.

The problem is clearly your migrations table. You can easily test it in a separate folder, just do:
KOLIBRI_HOME=/tmp/whatever kolibri start --foreground
after it starts you can stop it, and go to /tmp/whatever and open the db.sqlite3 file. You’ll check the django_migrations table contains more much than 3 rows. It seems pgloader didn’t do its work correctly.

HINT: If you execute the above command using kolibri 0.15.7 , then you can copy exactly the content of the django_migrations table in that temporary sqlite installation to your postgresql db, so you can work correctly.

José

Okay, I can see what the issue was and it came from my not understanding well enough how to convert things over:

First I loaded the databases by running pgloader on each of the sqllite files:

pgloader sqlite://db.sqlite3 pgsql://user:pass@endpoint/kolibri
pgloader sqlite://job_storage.sqlite3 pgsql://user:pass@endpoint/kolibri
pgloader sqlite://networklocation.sqlite3 pgsql://user:pass@endpoint/kolibri
pgloader sqlite://notifications.sqlite3 pgsql://user:pass@endpoint/kolibri
pgloader sqlite://syncqueue.sqlite3 pgsql://user:pass@endpoint/kolibri

Then I ran it on two of the channels that were installed to get their databases in there:

pgloader sqlite://1d8f6d84618153c18c695d85074952a7.sqlite3 pgsql://user:pass@endpoint/kolibri
pgloader sqlite://913efe9f14c65cb1b23402f21f056e99.sqlite3 pgsql://user:pass@endpoint/kolibri

It seems that the django_migrations is the contents of the last file processed.

What I should I have done instead, and what else may I have messed up in this process?

Sorry, I can’t help you with pgloader, I am not familiar with that application.

What I can tell you is that you need to have all the content for all the tables you have in sqlite inserted in your postgresql database.

The order doing it should not affect to the end result as far as you end having all the tables and their content copied. I don’t know if pgloader will handle correctly some data types that are not identical in sqlite and postgresql (as the id of some tables that are char in sqlite and uuid in postgresql)

José

Yeah, that totally makes sense. It just seems that the initial loading of content into the database did not go well. Pgloader was used to swap from SQLite into Postgres since (as far as I can tell) there is no way to just start with a Postgres DB from the start which completely makes sense for this application.

I guess what I was asking seemed that each sqlite3 file imported must have overwrote the table structure/contents so what might have gotten destroyed in that process. Like would something critical in the syncqueue file have altered tables that the main db file needed. Is that clear?

Regardless, I at least see what needs to happen at this point to get over this specific hurdle. Thank you for that guidance.

I’m not sure if I understand this. I you’re refering to kolibri, there’s no problem in starting to use it in Postgresql from scratch. You just need to create the database and its credentials, and add them to the options.ini file. Then, at the first start, kolibri will create all the tables with the right permissions/relations.

The way you’re doing it only makes sense if you want to keep old data from the students or classes the coaches created, if not I’d do it from scratch. It’s much easier and safer.

Maybe I did something wrong, but I swore upon installing Kolibri it automatically started things and thus the tables were already created before I got the chance to put anything into the options.ini file. Because of that I needed to migrate the files that were created.