IsharMud / ishar-web

3 stars 1 forks source link

Quest rewards primary key #12

Closed ericoc closed 1 year ago

ericoc commented 1 year ago

Problem

In order to administrate "Quest Rewards" from the Django administration interface, the quest_rewards table needs a new primary key column.

root@isharmud:~# mysql ishar -sse "SHOW CREATE TABLE quest_rewards \G;"
*************************** 1. row ***************************
       Table: quest_rewards
Create Table: CREATE TABLE `quest_rewards` (
  `reward_num` int(11) NOT NULL,
  `reward_type` tinyint(2) NOT NULL,
  `quest_id` int(11) unsigned NOT NULL,
  `class_restrict` tinyint(4) NOT NULL DEFAULT -1,
  PRIMARY KEY (`reward_num`,`quest_id`),
  KEY `quests_rewards_quest_id` (`quest_id`),
  CONSTRAINT `quests_rewards_quest_id` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`quest_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

I actually removed the primary key definition on the ishar_test.quest_rewards MySQL table, just to see if it made a difference:

root@isharmud:~# mysql ishar_test -sse "SHOW CREATE TABLE quest_rewards \G;"
*************************** 1. row ***************************
       Table: quest_rewards
Create Table: CREATE TABLE `quest_rewards` (
  `reward_num` int(11) NOT NULL,
  `reward_type` tinyint(2) NOT NULL,
  `quest_id` int(11) NOT NULL,
  `class_restrict` tinyint(4) NOT NULL DEFAULT -1,
  KEY `quests_rewards_quest_id` (`quest_id`),
  CONSTRAINT `quests_rewards_quest_id` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`quest_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

Cause

However, it turns out, "only single-column primary keys are supported" within Django...

https://docs.djangoproject.com/en/dev/faq/models/#do-django-models-support-multiple-column-primary-keys

"Do Django models support multiple-column primary keys?

"No. Only single-column primary keys are supported."

Temporary Half-Fix

Currently, I have primary_key=True set on the reward_num column within the Django model, in order to have the "Quests" page on the Django administration interface displaying at all:

https://github.com/IsharMud/ishar-web/blob/django/ishar/apps/quest/models/reward.py#L15

However, edits to quest rewards likely fail with various 500-level error codes at this time.

Solution

I am still not sure of the right move here, but I suspect that our best option may be to copy the way that "quest_steps" works - since there is a primary key of step_id.

https://github.com/IsharMud/ishar-web/blob/django/ishar/apps/quest/models/step.py

As far as I am aware, management of Quest Steps does indeed work properly and correctly in the Django administration interface.

root@isharmud:~# mysql ishar -sse "SHOW CREATE TABLE quest_steps \G;"
*************************** 1. row ***************************
       Table: quest_steps
Create Table: CREATE TABLE `quest_steps` (
  `step_id` tinyint(4) NOT NULL AUTO_INCREMENT,
  `step_type` tinyint(4) NOT NULL,
  `target` int(11) NOT NULL,
  `num_required` int(11) NOT NULL,
  `quest_id` int(11) unsigned NOT NULL,
  `time_limit` int(11) NOT NULL DEFAULT -1,
  `mystify` tinyint(1) NOT NULL DEFAULT 0,
  `mystify_text` varchar(80) NOT NULL DEFAULT '',
  PRIMARY KEY (`step_id`),
  KEY `quest_steps_quest_id` (`quest_id`),
  CONSTRAINT `quest_steps_quest_id` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`quest_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=71 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
root@isharmud:~# mysql ishar_test -sse "SHOW CREATE TABLE quest_steps \G;"
*************************** 1. row ***************************
       Table: quest_steps
Create Table: CREATE TABLE `quest_steps` (
  `step_id` tinyint(4) NOT NULL AUTO_INCREMENT,
  `step_type` tinyint(4) NOT NULL,
  `target` int(11) NOT NULL,
  `num_required` int(11) NOT NULL,
  `quest_id` int(11) NOT NULL,
  `time_limit` int(11) NOT NULL DEFAULT -1,
  `mystify` tinyint(1) NOT NULL DEFAULT 0,
  `mystify_text` varchar(80) NOT NULL DEFAULT '',
  PRIMARY KEY (`step_id`),
  KEY `quest_steps_quest_id` (`quest_id`),
  CONSTRAINT `quest_steps_quest_id` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`quest_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=72 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
Tyler-Jacob-F commented 1 year ago

This is complete -

new PK is "quest_reward_id"