{"action":"created","issue":{"url":"https://api.github.com/repos/deis/controller/issues/798","repository_url":"https://api.github.com/repos/deis/controller","labels_url":"https://api.github.com/repos/deis/controller/issues/798/labels{/name}","comments_url":"https://api.github.com/repos/deis/controller/issues/798/comments","events_url":"https://api.github.com/repos/deis/controller/issues/798/events","html_url":"https://github.com/deis/controller/issues/798","id":159184691,"number":798,"title":"Relationship between Release and Config / Build is the wrong way around","user":{"login":"helgi","id":70530,"avatar_url":"https://avatars.githubusercontent.com/u/70530?v=3","gravatar_id":"","url":"https://api.github.com/users/helgi","html_url":"https://github.com/helgi","followers_url":"https://api.github.com/users/helgi/followers","following_url":"https://api.github.com/users/helgi/following{/other_user}","gists_url":"https://api.github.com/users/helgi/gists{/gist_id}","starred_url":"https://api.github.com/users/helgi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/helgi/subscriptions","organizations_url":"https://api.github.com/users/helgi/orgs","repos_url":"https://api.github.com/users/helgi/repos","events_url":"https://api.github.com/users/helgi/events{/privacy}","received_events_url":"https://api.github.com/users/helgi/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2016-06-08T14:54:30Z","updated_at":"2016-06-08T15:51:13Z","closed_at":null,"body":"https://github.com/deis/controller/pull/792 has uncovered some inconsistencies in our data model on `Release`.\r\n\r\n### Problem\r\n\r\nCurrently things are set up so that `Release` is the child object of `Config` and `Build` via ForeignKey with CASCADE delete set.\r\n\r\nEach `Config` and `Build` object can be re-used across multiple `Release` objects, if nothing changes on the respective object. Such as: User A does 50 releases but they are only config changes, then the build object will always stay the same.\r\n\r\nIn many parts of the code when doing `deploy` and that fails we **only** delete the `Release` object, thinking the ForeignKey relationship is going to take care of it but that doesn't happen since `Release` is a child object, not a parent.\r\n\r\n#### Why is this a problem?\r\n\r\nIf only the `Release` object is remove then the `Config` object stays behind. When creating new releases it seems we are doing things like selecting the `latest` `Config` from the `App` or something... If the latest `Config` object is poisoned in a way that is hard to fix then.\r\n\r\nBasically the User ends up in a situation where it becomes pretty hard / impossible to recover from\r\n\r\n\r\n#### Experiment\r\n\r\nI did a quick experiment and used the DB directly after creating a few releases with combinations of config and build changes - First I tried deleting a release by hand, no config / build objects went away, and then I went and deleted a config object attached to 2 releases and both releases went away.\r\n\r\n### Potential solutions\r\n\r\nI reviewed a few solutions and how they would affect us\r\n\r\n* Flip the FK relationship around\r\n  * This would require the biggest rewrite as `Config` and `Build` objects can't be created without `Release`\r\n* Start programmatically handling the \"when to delete config / build as well\" and such\r\n  * Brittle as I will also have to look at all the `latest()` usages and try to reconcile things\r\n* Create a 1:1 between Release and Config/Build and severing the Config/Build tie with the `app_id` making Release the only connection, turning a Release into a ledger of sorts\r\n  * Allows us to treat the `Release` as an artefact but will make the DB bigger"},"comment":{"url":"https://api.github.com/repos/deis/controller/issues/comments/224634379","html_url":"https://github.com/deis/controller/issues/798#issuecomment-224634379","issue_url":"https://api.github.com/repos/deis/controller/issues/798","id":224634379,"user":{"login":"jchauncey","id":430360,"avatar_url":"https://avatars.githubusercontent.com/u/430360?v=3","gravatar_id":"","url":"https://api.github.com/users/jchauncey","html_url":"https://github.com/jchauncey","followers_url":"https://api.github.com/users/jchauncey/followers","following_url":"https://api.github.com/users/jchauncey/following{/other_user}","gists_url":"https://api.github.com/users/jchauncey/gists{/gist_id}","starred_url":"https://api.github.com/users/jchauncey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jchauncey/subscriptions","organizations_url":"https://api.github.com/users/jchauncey/orgs","repos_url":"https://api.github.com/users/jchauncey/repos","events_url":"https://api.github.com/users/jchauncey/events{/privacy}","received_events_url":"https://api.github.com/users/jchauncey/received_events","type":"User","site_admin":false},"created_at":"2016-06-08T15:51:12Z","updated_at":"2016-06-08T15:51:12Z","body":"<I am not a DBA> \r\n\r\nI think the third option seems the cleanest and most reasonable. If I understand correctly, every time a config value changes or a build changes we create a new release object. This is actually a pretty reasonable thing in my opinion. If you were doing releases manually and you needed to change config values that would more than likely result in a new release. "}}
{"actor":{"display_login":"jchauncey"}}