)]}'
{"keystone/common/sql/expand_repo/versions/046_expand_add_capability_tables.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"60506ea279f6645ecce20b1a2c4c52cae8adf139","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    application_credential_table \u003d sql.Table(\u0027application_credential\u0027, meta,"},{"line_number":22,"context_line":"                                             None, autoload\u003dTrue)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    url_path_template \u003d sql.Table("},{"line_number":25,"context_line":"        \u0027url_path_template\u0027, meta,"},{"line_number":26,"context_line":"        sql.Column(\u0027internal_id\u0027, sql.Integer, primary_key\u003dTrue,"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_a6d26fd0","line":23,"updated":"2018-06-06 15:04:57.000000000","message":"The JsonBlob implementation is provided by keystone in keystone.common.sql.core [0], in case you were looking to use that anywhere for your data (as opposed to Text or something else).\n\n[0] https://git.openstack.org/cgit/openstack/keystone/tree/keystone/common/sql/core.py#n119","commit_id":"c9626e53db05e4c6ec671649a2f83a3d228b7056"},{"author":{"_account_id":12542,"name":"Johannes Grassler","email":"jgr-launchpad@btw23.de","username":"jgrassler"},"change_message_id":"0003f5ac739bf2bf024b97f54d3ca3ffe9681434","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    application_credential_table \u003d sql.Table(\u0027application_credential\u0027, meta,"},{"line_number":22,"context_line":"                                             None, autoload\u003dTrue)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    url_path_template \u003d sql.Table("},{"line_number":25,"context_line":"        \u0027url_path_template\u0027, meta,"},{"line_number":26,"context_line":"        sql.Column(\u0027internal_id\u0027, sql.Integer, primary_key\u003dTrue,"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_ff48ea5c","line":23,"in_reply_to":"5f7c97a3_a6d26fd0","updated":"2018-06-06 16:21:05.000000000","message":"Thanks! Maybe for url_path_template_key and url_path_template_value. See next comment for a bit of a discussion.","commit_id":"c9626e53db05e4c6ec671649a2f83a3d228b7056"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"d3613d5f42f1a1ba2ffa34e079f1be0576dd75ef","unresolved":false,"context_lines":[{"line_number":27,"context_line":"                   nullable\u003dFalse),"},{"line_number":28,"context_line":"        sql.Column(\u0027id\u0027, sql.String(length\u003d64),"},{"line_number":29,"context_line":"                   nullable\u003dFalse),"},{"line_number":30,"context_line":"        sql.Column(\u0027template_string\u0027, sql.Text(), nullable\u003dFalse),"},{"line_number":31,"context_line":"        sql.Column(\u0027allow_chained\u0027, sql.Boolean(), nullable\u003dFalse,"},{"line_number":32,"context_line":"                   server_default\u003d\u00270\u0027),"},{"line_number":33,"context_line":"        sql.UniqueConstraint(\u0027id\u0027, name\u003d\u0027duplicate_id_constraint\u0027),"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_71547cc6","line":30,"range":{"start_line":30,"start_character":38,"end_line":30,"end_character":48},"updated":"2018-07-09 18:23:30.000000000","message":"Do we plan to enforce limits on how long a template string can be? If so, I assume that is something we\u0027re going to be doing in code?\n\nI\u0027m wondering how much we\u0027ll need to safe-guard against cases that might result in extreme database bloat.","commit_id":"c9626e53db05e4c6ec671649a2f83a3d228b7056"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"1c85d312cddd9a63eb343972d1fdfc256260ef88","unresolved":false,"context_lines":[{"line_number":27,"context_line":"                   nullable\u003dFalse),"},{"line_number":28,"context_line":"        sql.Column(\u0027id\u0027, sql.String(length\u003d64),"},{"line_number":29,"context_line":"                   nullable\u003dFalse),"},{"line_number":30,"context_line":"        sql.Column(\u0027template_string\u0027, sql.Text(), nullable\u003dFalse),"},{"line_number":31,"context_line":"        sql.Column(\u0027allow_chained\u0027, sql.Boolean(), nullable\u003dFalse,"},{"line_number":32,"context_line":"                   server_default\u003d\u00270\u0027),"},{"line_number":33,"context_line":"        sql.UniqueConstraint(\u0027id\u0027, name\u003d\u0027duplicate_id_constraint\u0027),"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_d12f903b","line":30,"range":{"start_line":30,"start_character":38,"end_line":30,"end_character":48},"in_reply_to":"5f7c97a3_71547cc6","updated":"2018-07-09 18:24:02.000000000","message":"I guess this comment also applies to other places where we\u0027re using sql.Text()","commit_id":"c9626e53db05e4c6ec671649a2f83a3d228b7056"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"26883683d31ba8e55470c8f2d4ee049afa12a82e","unresolved":false,"context_lines":[{"line_number":30,"context_line":"        sql.Column(\u0027template_string\u0027, sql.Text(), nullable\u003dFalse),"},{"line_number":31,"context_line":"        sql.Column(\u0027allow_chained\u0027, sql.Boolean(), nullable\u003dFalse,"},{"line_number":32,"context_line":"                   server_default\u003d\u00270\u0027),"},{"line_number":33,"context_line":"        sql.UniqueConstraint(\u0027id\u0027, name\u003d\u0027duplicate_id_constraint\u0027),"},{"line_number":34,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027,"},{"line_number":35,"context_line":"        mysql_charset\u003d\u0027utf8\u0027)"},{"line_number":36,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_38d6af55","line":33,"range":{"start_line":33,"start_character":41,"end_line":33,"end_character":64},"updated":"2018-06-20 15:38:06.000000000","message":"I think this needs a more specific name in order to identify it as related to this particular table","commit_id":"c9626e53db05e4c6ec671649a2f83a3d228b7056"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"74ef3f1ab8b90ff99bbae2f7a3815a45a7ffe432","unresolved":false,"context_lines":[{"line_number":30,"context_line":"        sql.Column(\u0027template_string\u0027, sql.Text(), nullable\u003dFalse),"},{"line_number":31,"context_line":"        sql.Column(\u0027allow_chained\u0027, sql.Boolean(), nullable\u003dFalse,"},{"line_number":32,"context_line":"                   server_default\u003d\u00270\u0027),"},{"line_number":33,"context_line":"        sql.UniqueConstraint(\u0027id\u0027, name\u003d\u0027duplicate_id_constraint\u0027),"},{"line_number":34,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027,"},{"line_number":35,"context_line":"        mysql_charset\u003d\u0027utf8\u0027)"},{"line_number":36,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_573642e9","line":33,"range":{"start_line":33,"start_character":41,"end_line":33,"end_character":64},"in_reply_to":"5f7c97a3_38d6af55","updated":"2018-07-05 23:19:36.000000000","message":"++, follow the general convention when naming constraints (look at past migrations/initial state migrations)","commit_id":"c9626e53db05e4c6ec671649a2f83a3d228b7056"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"74ef3f1ab8b90ff99bbae2f7a3815a45a7ffe432","unresolved":false,"context_lines":[{"line_number":42,"context_line":"                   sql.ForeignKey(application_credential_table.c.internal_id,"},{"line_number":43,"context_line":"                                  ondelete\u003d\u0027CASCADE\u0027),"},{"line_number":44,"context_line":"                   index\u003dTrue, nullable\u003dFalse),"},{"line_number":45,"context_line":"        sql.Column(\u0027id\u0027, sql.String(length\u003d64),"},{"line_number":46,"context_line":"                   nullable\u003dFalse),"},{"line_number":47,"context_line":"        sql.Column(\u0027url_path\u0027, sql.Text(),"},{"line_number":48,"context_line":"                   nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_977cda71","line":45,"range":{"start_line":45,"start_character":6,"end_line":45,"end_character":47},"updated":"2018-07-05 23:19:36.000000000","message":"Is this meant to be unique constrained and/or indexed?","commit_id":"c9626e53db05e4c6ec671649a2f83a3d228b7056"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"74ef3f1ab8b90ff99bbae2f7a3815a45a7ffe432","unresolved":false,"context_lines":[{"line_number":64,"context_line":"                   index\u003dTrue, nullable\u003dFalse),"},{"line_number":65,"context_line":"        sql.Column(\u0027key\u0027, sql.String(255),"},{"line_number":66,"context_line":"                   nullable\u003dFalse),"},{"line_number":67,"context_line":"        sql.Column(\u0027type\u0027, sql.Enum(\u0027context\u0027, \u0027user\u0027), nullable\u003dFalse),"},{"line_number":68,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027,"},{"line_number":69,"context_line":"        mysql_charset\u003d\u0027utf8\u0027)"},{"line_number":70,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_97a37aff","line":67,"range":{"start_line":67,"start_character":8,"end_line":67,"end_character":72},"updated":"2018-07-05 23:19:36.000000000","message":"Do *NOT* use ENUM types. If we ever have to expand it, the only solution is to migrate to a new table and expand the dataset (no-downtime upgrades/rolling upgrades -- the old app will error on the new ENUM type).\n\nEnforce the types strictly in code/business logic and ignore rows with an invalid enum type.\n\nAlso expand on what \"context\" type vs \"user\" type is.","commit_id":"c9626e53db05e4c6ec671649a2f83a3d228b7056"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"60506ea279f6645ecce20b1a2c4c52cae8adf139","unresolved":false,"context_lines":[{"line_number":81,"context_line":"        sql.Column(\u0027value\u0027, sql.String(255),"},{"line_number":82,"context_line":"                   nullable\u003dTrue),"},{"line_number":83,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027,"},{"line_number":84,"context_line":"        mysql_charset\u003d\u0027utf8\u0027)"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    url_path_template.create(migrate_engine, checkfirst\u003dTrue)"},{"line_number":87,"context_line":"    capability.create(migrate_engine, checkfirst\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_c6bc4b6e","line":84,"updated":"2018-06-06 15:04:57.000000000","message":"I might not be understanding something completely, but these last two tables seem to have a lot in common. Is there an advantage to keeping them separated?","commit_id":"c9626e53db05e4c6ec671649a2f83a3d228b7056"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"74ef3f1ab8b90ff99bbae2f7a3815a45a7ffe432","unresolved":false,"context_lines":[{"line_number":81,"context_line":"        sql.Column(\u0027value\u0027, sql.String(255),"},{"line_number":82,"context_line":"                   nullable\u003dTrue),"},{"line_number":83,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027,"},{"line_number":84,"context_line":"        mysql_charset\u003d\u0027utf8\u0027)"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    url_path_template.create(migrate_engine, checkfirst\u003dTrue)"},{"line_number":87,"context_line":"    capability.create(migrate_engine, checkfirst\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_7769febd","line":84,"in_reply_to":"5f7c97a3_1b2fcc3e","updated":"2018-07-05 23:19:36.000000000","message":"I\u0027m spending a large amount of time on the data model here, and I simply don\u0027t see how this is translating into code [this is a pretty dense model]. I\u0027d like to see the code that will use this so I can understand clearly the template_key and template_value.\n\n\nI get the feeling that this is over-normalizing data, but with the code this might make a lot more sense.","commit_id":"c9626e53db05e4c6ec671649a2f83a3d228b7056"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"26883683d31ba8e55470c8f2d4ee049afa12a82e","unresolved":false,"context_lines":[{"line_number":81,"context_line":"        sql.Column(\u0027value\u0027, sql.String(255),"},{"line_number":82,"context_line":"                   nullable\u003dTrue),"},{"line_number":83,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027,"},{"line_number":84,"context_line":"        mysql_charset\u003d\u0027utf8\u0027)"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    url_path_template.create(migrate_engine, checkfirst\u003dTrue)"},{"line_number":87,"context_line":"    capability.create(migrate_engine, checkfirst\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_1b2fcc3e","line":84,"in_reply_to":"5f7c97a3_5f447e19","updated":"2018-06-20 15:38:06.000000000","message":"I\u0027m still trying to wrap my head around this schema but my gut feeling is that if it\u0027s really this complex then it would actually be better to manage it in code and not try to model it in the DB.","commit_id":"c9626e53db05e4c6ec671649a2f83a3d228b7056"},{"author":{"_account_id":12542,"name":"Johannes Grassler","email":"jgr-launchpad@btw23.de","username":"jgrassler"},"change_message_id":"0003f5ac739bf2bf024b97f54d3ca3ffe9681434","unresolved":false,"context_lines":[{"line_number":81,"context_line":"        sql.Column(\u0027value\u0027, sql.String(255),"},{"line_number":82,"context_line":"                   nullable\u003dTrue),"},{"line_number":83,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027,"},{"line_number":84,"context_line":"        mysql_charset\u003d\u0027utf8\u0027)"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    url_path_template.create(migrate_engine, checkfirst\u003dTrue)"},{"line_number":87,"context_line":"    capability.create(migrate_engine, checkfirst\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_5f447e19","line":84,"in_reply_to":"5f7c97a3_c6bc4b6e","updated":"2018-06-06 16:21:05.000000000","message":"They are, yes. I\u0027m keeping them separated to avoid the awkwardness of having two foreign key constraints, one of which always needs to be null if the other is not null.\n\nFor one of these tables forms the list of allowable keys for url path templates (and thus references that table). While the other one holds templates to interpolate for interpolation into a capability (and thus references the capability table). It would be technically possible to complain them, but I\u0027d prefer this clean separation.\n\nAlternatively, one could turn both or either of these into JsonBlob columns, but I\u0027m not really fond of that idea since,  being a blob, it is opaque. I\u0027d prefer defining these lists\u0027 structure through the database schema rather than having it hidden away in the code somewhere.","commit_id":"c9626e53db05e4c6ec671649a2f83a3d228b7056"}]}
