Upgrades are failing for Postgres in case data is updated after schema alterations in this migration:
Failure is Cannot ALTER TABLE device_devicesettings because it has pending trigger events
More info: https://stackoverflow.com/a/12838113
We have a test environment run on Postgres, but we are not testing our migrations with data, so we cannot know if they actually work. How do we solve this?
Gherkin?
User can use 0.12, add something to device_devicesettings and upgrade Kolibri afterwards.
TBC
TBC
n/a
Kolibri 0.12 upgrade to 0.13.0
My PR fixes the issue, but still leaves open the question how to catch these types of errors in the future. A non-automated solution could be gherkins as suggested by @benjaoming, but we should flag them for "risky" migrations. Another one could be more stringent review of PRs that add migrations. As we learn about these types of migration issues and learn how to deal with them, we could create a template of things to check/test for in migrations.
I think the simplest automated solution would be to make a custom linting rule that ensures that RunPython operations never occur anywhere but as the last element of migrations (in the case where there are operations other than RunPython)? That should catch the majority of cases, I think.
Another one could be more stringent review of PRs that add migrations.
Yes, I have often fantasized about adding linting on migrations, as I don't like when they're called 0123_auto_some_timestamp - names should be verbose etc.
Data migrations and schema migrations should not be mixed, would be great to catch this in linting as well, really good idea @rtibbles ! :+1:
created follow-up issues related to linting:
RunPython behavior)Fixed in #6488
I confirm that #6488 fixed the issue: specifically the exception during upgrade from v0.12.2 to v0.13.0 using PostgreSQL-9.5.
Here are the steps to reproduce it, I suggest to use a Virtual Machine so you can take snapshots:
Environment
postgresql-9.5 and; postgresql-server-dev-9.5 -- needed by the Python library psycopg2 so we can use PostgreSQL in Djangopython3-pip via Apt Kolibri Installers Used
Setup PostgreSQL-9.5
Create a Kolibri database and user to be used to access it:
sudo apt-get install postgresql-9.5 postgresql-server-dev-9.5sudo -u postgres psqlcreate database kolibri;CREATE USER kolibri WITH PASSWORD ‘password’;ALTER ROLE kolibri SET client_encoding TO 'utf8';ALTER ROLE kolibri SET default_transaction_isolation TO 'read committed';ALTER ROLE kolibri SET timezone TO 'UTC';GRANT ALL PRIVILEGES ON DATABASE kolibri TO kolibri;psycopg2 by running these:sudo apt-get install python3-pippip3 install psycopg2Reproduce the Issue
~/.kolibri/options.ini file with this content[Database]
DATABASE_ENGINE=postgres
DATABASE_NAME=kolibri
DATABASE_USER=kolibri
DATABASE_PASSWORD=password
DATABASE_HOST=127.0.0.1
DATABASE_PORT=5432
kolibri start -- this will run the migrations and start Kolibri which should now use the Kolibri PostgreSQL database.kolibri stop.kolibri status afterwards - notice that it shows Kolibri is stopped.kolibri start to see the exception: ...
Running migrations:
Applying device.0005_auto_20191203_0951...Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/kolibri/dist/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
psycopg2.errors.ObjectInUse: cannot ALTER TABLE "device_devicesettings" because it has pending trigger events
...
To Verify the Fix
kolibri-buildkite-build-6488-13326-kolibri_0.13.1a0.dev0 installer instead.kolibri status afterwards shows the Kolibri URLs where it's running.Some Notes
Next Step/s
@radinamatic note the steps that @cpauya has found for Postgres above.
A little extra note for Postgres stuff: It's possible to assign access to a Postgres user without setting a password for the role, if we use the Peer authentication mechanism for local connections. This will also use a Unix socket which is faster. I mean, it's for when we want to simplify instructions in a tutorial or automated setup for using Postgres.