juanifioren/django-oidc-provider

migrations/0026_client_multiple_response_types.py fails in cx_Oracle 6.4.x

zulrang opened this issue · 0 comments

See the sqlmigrate dump below:

$ python manage.py sqlmigrate oidc_provider 0026

--
-- Create model ResponseType
--
CREATE TABLE "OIDC_PROVIDER_RESPONSETYPE" ("ID" NUMBER(11) NOT NULL PRIMARY KEY, "VALUE" NVARCHAR2(30) NULL UNIQUE, "DESCRIPTION" NVARCHAR2(50) NULL);
--
-- Add field response_types to client
--
CREATE TABLE "OIDC_PROVIDER_CLIENT_RESPO72A5" ("ID" NUMBER(11) NOT NULL PRIMARY KEY, "CLIENT_ID" NUMBER(11) NOT NULL, "RESPONSETYPE_ID" NUMBER(11) NOT NULL);
--
-- MIGRATION NOW PERFORMS OPERATION THAT CANNOT BE WRITTEN AS SQL:
-- Raw Python operation
--
--
-- Remove field response_type from client
--
ALTER TABLE "OIDC_PROVIDER_CLIENT" DROP COLUMN "RESPONSE_TYPE";

DECLARE
    i INTEGER;
BEGIN
    SELECT COUNT(1) INTO i FROM USER_SEQUENCES
        WHERE SEQUENCE_NAME = 'OIDC_PROVIDER_RESPONSETYPE_SQ';
    IF i = 0 THEN
        EXECUTE IMMEDIATE 'CREATE SEQUENCE "OIDC_PROVIDER_RESPONSETYPE_SQ"';
    END IF;
END;
/;

CREATE OR REPLACE TRIGGER "OIDC_PROVIDER_RESPONSETYPE_TR"
BEFORE INSERT ON "OIDC_PROVIDER_RESPONSETYPE"
FOR EACH ROW
WHEN (new."ID" IS NULL)
    BEGIN
        SELECT "OIDC_PROVIDER_RESPONSETYPE_SQ".nextval
        INTO :new."ID" FROM dual;
    END;
/;

DECLARE
    i INTEGER;
BEGIN
    SELECT COUNT(1) INTO i FROM USER_SEQUENCES
        WHERE SEQUENCE_NAME = 'OIDC_PROVIDER_CLIENT_RE8C2C_SQ';
    IF i = 0 THEN
        EXECUTE IMMEDIATE 'CREATE SEQUENCE "OIDC_PROVIDER_CLIENT_RE8C2C_SQ"';
    END IF;
END;
/;

CREATE OR REPLACE TRIGGER "OIDC_PROVIDER_CLIENT_RE8C2C_TR"
BEFORE INSERT ON "OIDC_PROVIDER_CLIENT_RESPO72A5"
FOR EACH ROW
WHEN (new."ID" IS NULL)
    BEGIN
        SELECT "OIDC_PROVIDER_CLIENT_RE8C2C_SQ".nextval
        INTO :new."ID" FROM dual;
    END;
/;
ALTER TABLE "OIDC_PROVIDER_CLIENT_RESPO72A5" ADD CONSTRAINT "OIDC_PROV_CLIENT_ID_72720BDA_F" FOREIGN KEY ("CLIENT_ID") REFERENCES "OIDC_PROVIDER_CLIENT" ("ID") DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE "OIDC_PROVIDER_CLIENT_RESPO72A5" ADD CONSTRAINT "OIDC_PROV_RESPONSET_A381917A_F" FOREIGN KEY ("RESPONSETYPE_ID") REFERENCES "OIDC_PROVIDER_RESPONSETYPE" ("ID") DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE "OIDC_PROVIDER_CLIENT_RESPO72A5" ADD CONSTRAINT "OIDC_PROV_CLIENT_ID_4DC420E2_U" UNIQUE ("CLIENT_ID", "RESPONSETYPE_ID");
CREATE INDEX "OIDC_PROVI_CLIENT_ID_72720BDA" ON "OIDC_PROVIDER_CLIENT_RESPO72A5" ("CLIENT_ID");
CREATE INDEX "OIDC_PROVI_RESPONSETY_A381917A" ON "OIDC_PROVIDER_CLIENT_RESPO72A5" ("RESPONSETYPE_ID");
COMMIT;

Note that the migrations.RunPython(migrate_response_type) is run BEFORE the sequences/triggers are created, meaning that it fails when it tries to insert into ResponseTypes into the database (because ID is NULL).

Data migrations should be separate from schema migrations (https://docs.djangoproject.com/en/3.0/topics/migrations/#data-migrations) which prevents these types of issues.