Skip to content

Add deferrable FK utility, test case, and migration#341

Open
bjester wants to merge 2 commits into
learningequality:release-v0.8.xfrom
bjester:make-deferrable-pls
Open

Add deferrable FK utility, test case, and migration#341
bjester wants to merge 2 commits into
learningequality:release-v0.8.xfrom
bjester:make-deferrable-pls

Conversation

@bjester

@bjester bjester commented Jun 26, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds utility for updating existing FK constraints, that are immediate by default, to have a deferrable flag
    • This corrects an issue where databases that were created prior to Django 3.1 did not set the deferrable flag, and after that, Django enabled FK checks by default. Django relies on deferrable FK constraints for its cascade deletion because it executes deletions out of order (as shown in the issue).
    • The utility works for both a Django migration and manual invocation, such that Kolibri can include it as a version upgrade migration.
  • A Django migration was added to invoke the utility explicitly for morango models automatically
  • A test verifies the proof-of-concept of how the utility operates, including its preservation of data

Creation of this utility was started in Kolibri, when it was realized other apps (like Morango) may need this. Since Morango is a standalone package with respect to Kolibri, the utility was added here, made to automatically handle morango models, and to allow Kolibri to leverage the utility in its own way.

Reviewer guidance

  • Are the tests sufficient?
  • Is there test coverage lacking?

I ran Kolibri 0.16.2 to generate an old database with the issue, along with some data (classes and users). With these changes integrated into Kolibri, I then ran both via a Kolibri upgrade on top of the the 0.16.2 home, to verify that it updated the FK constraints. All data was preserved.

I can provide the 0.16.2 home upon request.

Before (0.16.2)

sqlite> .schema kolibriauth_collection
CREATE TABLE IF NOT EXISTS "kolibriauth_collection" (
  "id" char(32) NOT NULL PRIMARY KEY, 
  "_morango_dirty_bit" bool NOT NULL,
   "_morango_source_id" varchar(96) NOT NULL, 
  "_morango_partition" varchar(128) NOT NULL, 
  "name" varchar(100) NOT NULL, 
  "kind" varchar(20) NOT NULL, 
  "dataset_id" char(32) NOT NULL REFERENCES "kolibriauth_facilitydataset" ("id"), 
  "parent_id" char(32) NULL REFERENCES "kolibriauth_collection" ("id")
);

After (pending 0.19.5)

sqlite> .schema kolibriauth_collection
CREATE TABLE IF NOT EXISTS "kolibriauth_collection" (
  "id" char(32) NOT NULL PRIMARY KEY, 
  "_morango_dirty_bit" bool NOT NULL, 
  "_morango_source_id" varchar(96) NOT NULL, 
  "_morango_partition" varchar(128) NOT NULL, 
  "dataset_id" char(32) NOT NULL REFERENCES "kolibriauth_facilitydataset" ("id") DEFERRABLE INITIALLY DEFERRED,
  "name" varchar(100) NOT NULL, 
  "kind" varchar(20) NOT NULL, 
  "parent_id" char(32) NULL REFERENCES "kolibriauth_collection" ("id") DEFERRABLE INITIALLY DEFERRED
);

Issues addressed

Supports resolution of learningequality/kolibri#14884

AI Usage

Creation of this utility was started in Kolibri with AI. It generated the bulk of the utility and the test, then it was brought over to Morango, and a human refactored the utility to make it flexible for both Morango and Kolibri, and to isolate looping over applications.

@bjester bjester marked this pull request as ready for review June 26, 2026 20:47
@bjester bjester requested a review from rtibblesbot June 26, 2026 21:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant