diff --git a/tasks/migrations/0005_fix_tasks_tags_table.py b/tasks/migrations/0005_fix_tasks_tags_table.py index 2c2d3f0..1cc35fd 100644 --- a/tasks/migrations/0005_fix_tasks_tags_table.py +++ b/tasks/migrations/0005_fix_tasks_tags_table.py @@ -10,21 +10,53 @@ def fix_tasks_tags_table(apps, schema_editor): """ db_alias = schema_editor.connection.alias + # Check database type + is_postgres = schema_editor.connection.vendor == 'postgresql' + is_mysql = schema_editor.connection.vendor == 'mysql' + # Drop and recreate the tasks_tags table with correct foreign keys schema_editor.execute( - "DROP TABLE IF EXISTS tasks_tags;" + "DROP TABLE IF EXISTS tasks_tags CASCADE;" if is_postgres else "DROP TABLE IF EXISTS tasks_tags;" ) - schema_editor.execute( - """ - CREATE TABLE tasks_tags ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - task_id CHAR(32) NOT NULL REFERENCES tasks(id) ON DELETE CASCADE, - tag_id CHAR(32) NOT NULL REFERENCES tags(id) ON DELETE CASCADE, - UNIQUE (task_id, tag_id) - ); - """ - ) + if is_postgres: + # PostgreSQL syntax + schema_editor.execute( + """ + CREATE TABLE tasks_tags ( + id SERIAL PRIMARY KEY, + task_id UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE, + tag_id UUID NOT NULL REFERENCES tags(id) ON DELETE CASCADE, + UNIQUE (task_id, tag_id) + ); + """ + ) + elif is_mysql: + # MySQL/MariaDB syntax + schema_editor.execute( + """ + CREATE TABLE tasks_tags ( + id INTEGER PRIMARY KEY AUTO_INCREMENT, + task_id CHAR(32) NOT NULL, + tag_id CHAR(32) NOT NULL, + UNIQUE (task_id, tag_id), + FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE, + FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE + ); + """ + ) + else: + # SQLite syntax (default) + schema_editor.execute( + """ + CREATE TABLE tasks_tags ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + task_id CHAR(32) NOT NULL REFERENCES tasks(id) ON DELETE CASCADE, + tag_id CHAR(32) NOT NULL REFERENCES tags(id) ON DELETE CASCADE, + UNIQUE (task_id, tag_id) + ); + """ + ) # Create indexes for performance schema_editor.execute( diff --git a/tasks/migrations/0006_fix_task_shares_table.py b/tasks/migrations/0006_fix_task_shares_table.py index b18bece..af0f9ad 100644 --- a/tasks/migrations/0006_fix_task_shares_table.py +++ b/tasks/migrations/0006_fix_task_shares_table.py @@ -10,30 +10,82 @@ def fix_task_shares_table(apps, schema_editor): """ db_alias = schema_editor.connection.alias + # Check database type + is_postgres = schema_editor.connection.vendor == 'postgresql' + is_mysql = schema_editor.connection.vendor == 'mysql' + # Drop and recreate the task_shares table with correct foreign keys schema_editor.execute( - "DROP TABLE IF EXISTS task_shares;" + "DROP TABLE IF EXISTS task_shares CASCADE;" if is_postgres else "DROP TABLE IF EXISTS task_shares;" ) - schema_editor.execute( - """ - CREATE TABLE task_shares ( - id CHAR(32) NOT NULL PRIMARY KEY, - permission VARCHAR(20) NOT NULL, - sync_id CHAR(32) NOT NULL UNIQUE, - created_at DATETIME NOT NULL, - updated_at DATETIME NOT NULL, - owner_id CHAR(32) NOT NULL REFERENCES users(id) DEFERRABLE INITIALLY DEFERRED, - shared_with_id CHAR(32) NOT NULL REFERENCES users(id) DEFERRABLE INITIALLY DEFERRED, - task_id CHAR(32) NULL REFERENCES tasks(id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, - tag_id CHAR(32) NULL REFERENCES tags(id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, - CONSTRAINT share_task_or_tag_not_both CHECK ( - (tag_id IS NULL AND task_id IS NOT NULL) OR - (tag_id IS NOT NULL AND task_id IS NULL) - ) - ); - """ - ) + if is_postgres: + # PostgreSQL syntax + schema_editor.execute( + """ + CREATE TABLE task_shares ( + id UUID NOT NULL PRIMARY KEY, + permission VARCHAR(20) NOT NULL, + sync_id UUID NOT NULL UNIQUE, + created_at TIMESTAMP NOT NULL, + updated_at TIMESTAMP NOT NULL, + owner_id UUID NOT NULL REFERENCES users(id) DEFERRABLE INITIALLY DEFERRED, + shared_with_id UUID NOT NULL REFERENCES users(id) DEFERRABLE INITIALLY DEFERRED, + task_id UUID NULL REFERENCES tasks(id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, + tag_id UUID NULL REFERENCES tags(id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, + CONSTRAINT share_task_or_tag_not_both CHECK ( + (tag_id IS NULL AND task_id IS NOT NULL) OR + (tag_id IS NOT NULL AND task_id IS NULL) + ) + ); + """ + ) + elif is_mysql: + # MySQL/MariaDB syntax + schema_editor.execute( + """ + CREATE TABLE task_shares ( + id CHAR(32) NOT NULL PRIMARY KEY, + permission VARCHAR(20) NOT NULL, + sync_id CHAR(32) NOT NULL UNIQUE, + created_at DATETIME NOT NULL, + updated_at DATETIME NOT NULL, + owner_id CHAR(32) NOT NULL, + shared_with_id CHAR(32) NOT NULL, + task_id CHAR(32) NULL, + tag_id CHAR(32) NULL, + CONSTRAINT share_task_or_tag_not_both CHECK ( + (tag_id IS NULL AND task_id IS NOT NULL) OR + (tag_id IS NOT NULL AND task_id IS NULL) + ), + FOREIGN KEY (owner_id) REFERENCES users(id), + FOREIGN KEY (shared_with_id) REFERENCES users(id), + FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE, + FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE + ); + """ + ) + else: + # SQLite syntax (default) + schema_editor.execute( + """ + CREATE TABLE task_shares ( + id CHAR(32) NOT NULL PRIMARY KEY, + permission VARCHAR(20) NOT NULL, + sync_id CHAR(32) NOT NULL UNIQUE, + created_at DATETIME NOT NULL, + updated_at DATETIME NOT NULL, + owner_id CHAR(32) NOT NULL REFERENCES users(id) DEFERRABLE INITIALLY DEFERRED, + shared_with_id CHAR(32) NOT NULL REFERENCES users(id) DEFERRABLE INITIALLY DEFERRED, + task_id CHAR(32) NULL REFERENCES tasks(id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, + tag_id CHAR(32) NULL REFERENCES tags(id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, + CONSTRAINT share_task_or_tag_not_both CHECK ( + (tag_id IS NULL AND task_id IS NOT NULL) OR + (tag_id IS NOT NULL AND task_id IS NULL) + ) + ); + """ + ) # Create indexes for foreign keys schema_editor.execute(