)]}'
{"neutron/db/migration/alembic_migrations/versions/victoria/expand/f010820fc498_add_unique_quotas_project_resource.py":[{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"79e8ca6289866397535d33c1ae13d87de150f446","unresolved":false,"context_lines":[{"line_number":19,"context_line":"\"\"\"add_unique_quotas_project_resource"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"Revision ID: f010820fc498"},{"line_number":22,"context_line":"Revises: fd6107509ccd"},{"line_number":23,"context_line":"Create Date: 2020-08-28 14:49:50.615623"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"\"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"3f65232a_47f51ccb","line":22,"range":{"start_line":22,"start_character":9,"end_line":22,"end_character":21},"updated":"2020-10-23 06:58:00.000000000","message":"please update as well","commit_id":"0bded297e3acb07032574f65ddbc23371ab5c143"},{"author":{"_account_id":30380,"name":"ZhouHeng","email":"zhouhenglc@inspur.com","username":"zhouhenglc"},"change_message_id":"4e39c9571b90befc715cbfc7ac684c7cf02582ff","unresolved":false,"context_lines":[{"line_number":19,"context_line":"\"\"\"add_unique_quotas_project_resource"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"Revision ID: f010820fc498"},{"line_number":22,"context_line":"Revises: fd6107509ccd"},{"line_number":23,"context_line":"Create Date: 2020-08-28 14:49:50.615623"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"\"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"3f65232a_b2bf0cfa","line":22,"range":{"start_line":22,"start_character":9,"end_line":22,"end_character":21},"in_reply_to":"3f65232a_47f51ccb","updated":"2020-10-23 08:08:38.000000000","message":"thanks, do you know why zuul -1?","commit_id":"0bded297e3acb07032574f65ddbc23371ab5c143"},{"author":{"_account_id":30380,"name":"ZhouHeng","email":"zhouhenglc@inspur.com","username":"zhouhenglc"},"change_message_id":"288f0ced8ed0302948f8993d5e98799facc06484","unresolved":false,"context_lines":[{"line_number":19,"context_line":"\"\"\"add_unique_quotas_project_resource"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"Revision ID: f010820fc498"},{"line_number":22,"context_line":"Revises: fd6107509ccd"},{"line_number":23,"context_line":"Create Date: 2020-08-28 14:49:50.615623"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"\"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"3f65232a_529f984f","line":22,"range":{"start_line":22,"start_character":9,"end_line":22,"end_character":21},"in_reply_to":"3f65232a_72f8d4c3","updated":"2020-10-23 08:31:43.000000000","message":"thank you!","commit_id":"0bded297e3acb07032574f65ddbc23371ab5c143"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"03322075e76b6309092a869f9e0d6d092f823275","unresolved":false,"context_lines":[{"line_number":19,"context_line":"\"\"\"add_unique_quotas_project_resource"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"Revision ID: f010820fc498"},{"line_number":22,"context_line":"Revises: fd6107509ccd"},{"line_number":23,"context_line":"Create Date: 2020-08-28 14:49:50.615623"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"\"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"3f65232a_72f8d4c3","line":22,"range":{"start_line":22,"start_character":9,"end_line":22,"end_character":21},"in_reply_to":"3f65232a_b2bf0cfa","updated":"2020-10-23 08:15:35.000000000","message":"Migration creates index while model adds constraint. You need to update migration to create constraint, not just unique index.","commit_id":"0bded297e3acb07032574f65ddbc23371ab5c143"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"a09df8359dc500c337904b2ea70231aca58f3f37","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"def upgrade():"},{"line_number":34,"context_line":"    op.create_index("},{"line_number":35,"context_line":"        op.f(\u0027uniq_quotas0project_id0resource\u0027),"},{"line_number":36,"context_line":"        \u0027quotas\u0027,"},{"line_number":37,"context_line":"        [\u0027project_id\u0027, \u0027resource\u0027], unique\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":5,"id":"3f65232a_122d2043","line":34,"range":{"start_line":34,"start_character":4,"end_line":34,"end_character":19},"updated":"2020-10-23 08:16:48.000000000","message":"op.create_unique_constraint","commit_id":"0bded297e3acb07032574f65ddbc23371ab5c143"},{"author":{"_account_id":30380,"name":"ZhouHeng","email":"zhouhenglc@inspur.com","username":"zhouhenglc"},"change_message_id":"288f0ced8ed0302948f8993d5e98799facc06484","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"def upgrade():"},{"line_number":34,"context_line":"    op.create_index("},{"line_number":35,"context_line":"        op.f(\u0027uniq_quotas0project_id0resource\u0027),"},{"line_number":36,"context_line":"        \u0027quotas\u0027,"},{"line_number":37,"context_line":"        [\u0027project_id\u0027, \u0027resource\u0027], unique\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":5,"id":"3f65232a_b2ac2c8d","line":34,"range":{"start_line":34,"start_character":4,"end_line":34,"end_character":19},"in_reply_to":"3f65232a_122d2043","updated":"2020-10-23 08:31:43.000000000","message":"Done","commit_id":"0bded297e3acb07032574f65ddbc23371ab5c143"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"f112a586d09cfafcba89848c0731d27e094cff32","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"3f65232a_aac66266","updated":"2020-10-26 07:58:30.000000000","message":"This should be moved to wallaby folder.","commit_id":"2d399b348b2d27a5e6826b8e412885a0bcc070c7"},{"author":{"_account_id":30380,"name":"ZhouHeng","email":"zhouhenglc@inspur.com","username":"zhouhenglc"},"change_message_id":"a84e96a9dac58a69e4b1493755c64de9a12eb70b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"3f65232a_ca763e07","in_reply_to":"3f65232a_aac66266","updated":"2020-10-26 08:17:32.000000000","message":"Done","commit_id":"2d399b348b2d27a5e6826b8e412885a0bcc070c7"}],"neutron/db/migration/alembic_migrations/versions/wallaby/expand/f010820fc498_add_unique_quotas_project_resource.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"22f7ec0a10a64291fee2c4110fa7459981d37b5f","unresolved":false,"context_lines":[{"line_number":34,"context_line":"    op.create_unique_constraint("},{"line_number":35,"context_line":"        op.f(\u0027uniq_quotas0project_id0resource\u0027),"},{"line_number":36,"context_line":"        \u0027quotas\u0027,"},{"line_number":37,"context_line":"        [\u0027project_id\u0027, \u0027resource\u0027])"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f65232a_3b84620c","line":37,"updated":"2020-10-26 12:55:18.000000000","message":"I totally agree with the idea of solving the problem you reported using the DB and I\u0027ll +2 once you address the following comment.\n\nThis is, by definition, a contract action. Of course, we don\u0027t allow them anymore... more or less. This constrain you are adding should be fulfilled in any deployment. Of course, if any other user has the same problem as you reported in the bug, this migration will fail.\n\nYou should add first a check to find any possible register (or set of registers) not satisfying this constrain and raise an exception. The user should fix this manually in the DB.","commit_id":"6a1ea75bafb953547f6b3c985a042c8cca653c15"},{"author":{"_account_id":30380,"name":"ZhouHeng","email":"zhouhenglc@inspur.com","username":"zhouhenglc"},"change_message_id":"82d116dbd77ec572fabffbc876cde96e25c5dafe","unresolved":false,"context_lines":[{"line_number":34,"context_line":"    op.create_unique_constraint("},{"line_number":35,"context_line":"        op.f(\u0027uniq_quotas0project_id0resource\u0027),"},{"line_number":36,"context_line":"        \u0027quotas\u0027,"},{"line_number":37,"context_line":"        [\u0027project_id\u0027, \u0027resource\u0027])"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f65232a_cbe759e4","line":37,"in_reply_to":"3f65232a_3b84620c","updated":"2020-10-27 01:25:58.000000000","message":"Done","commit_id":"6a1ea75bafb953547f6b3c985a042c8cca653c15"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"1ef52b6ac939e5a1535658b1cd27b512f6fc3025","unresolved":false,"context_lines":[{"line_number":31,"context_line":"# revision identifiers, used by Alembic."},{"line_number":32,"context_line":"revision \u003d \u0027f010820fc498\u0027"},{"line_number":33,"context_line":"down_revision \u003d \u0027I38991de2b4\u0027"},{"line_number":34,"context_line":"depends_on \u003d (\u00277d9d8eeec6ad\u0027,)"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"quotas \u003d sa.Table("}],"source_content_type":"text/x-python","patch_set":10,"id":"3f65232a_d51fe16d","line":34,"range":{"start_line":34,"start_character":15,"end_line":34,"end_character":27},"updated":"2020-10-28 05:02:26.000000000","message":"why is it needed? Contract migrations could be squashed soon so we better not depend on particular ones.","commit_id":"210f0d5a2d7277a059b07c9ef7d765ead3075a04"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"94779c930db1bc1d46177d662b477fcf38c4eba6","unresolved":false,"context_lines":[{"line_number":31,"context_line":"# revision identifiers, used by Alembic."},{"line_number":32,"context_line":"revision \u003d \u0027f010820fc498\u0027"},{"line_number":33,"context_line":"down_revision \u003d \u0027I38991de2b4\u0027"},{"line_number":34,"context_line":"depends_on \u003d (\u00277d9d8eeec6ad\u0027,)"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"quotas \u003d sa.Table("}],"source_content_type":"text/x-python","patch_set":10,"id":"1f621f24_f39d3067","line":34,"range":{"start_line":34,"start_character":15,"end_line":34,"end_character":27},"in_reply_to":"1f621f24_d3fe34ad","updated":"2020-10-28 05:58:17.000000000","message":"hm, but the order of migrations is defined, how could newton migration be skipped or run after this one? Otherwise I guess a lot of migrations would need this depends_on section..","commit_id":"210f0d5a2d7277a059b07c9ef7d765ead3075a04"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"be3e1b8b2cbfc47dfe74906e60953a5ab254008a","unresolved":false,"context_lines":[{"line_number":31,"context_line":"# revision identifiers, used by Alembic."},{"line_number":32,"context_line":"revision \u003d \u0027f010820fc498\u0027"},{"line_number":33,"context_line":"down_revision \u003d \u0027I38991de2b4\u0027"},{"line_number":34,"context_line":"depends_on \u003d (\u00277d9d8eeec6ad\u0027,)"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"quotas \u003d sa.Table("}],"source_content_type":"text/x-python","patch_set":10,"id":"1f621f24_36fe7605","line":34,"range":{"start_line":34,"start_character":15,"end_line":34,"end_character":27},"in_reply_to":"1f621f24_f376d03e","updated":"2020-10-28 07:16:05.000000000","message":"ah, right","commit_id":"210f0d5a2d7277a059b07c9ef7d765ead3075a04"},{"author":{"_account_id":30380,"name":"ZhouHeng","email":"zhouhenglc@inspur.com","username":"zhouhenglc"},"change_message_id":"5b7eaf9ff3bda68221efe6c93940ee7881e6b94b","unresolved":false,"context_lines":[{"line_number":31,"context_line":"# revision identifiers, used by Alembic."},{"line_number":32,"context_line":"revision \u003d \u0027f010820fc498\u0027"},{"line_number":33,"context_line":"down_revision \u003d \u0027I38991de2b4\u0027"},{"line_number":34,"context_line":"depends_on \u003d (\u00277d9d8eeec6ad\u0027,)"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"quotas \u003d sa.Table("}],"source_content_type":"text/x-python","patch_set":10,"id":"1f621f24_f376d03e","line":34,"range":{"start_line":34,"start_character":15,"end_line":34,"end_character":27},"in_reply_to":"1f621f24_f39d3067","updated":"2020-10-28 06:01:54.000000000","message":"rename_tentan_to_project in `contract` not in `expand`","commit_id":"210f0d5a2d7277a059b07c9ef7d765ead3075a04"},{"author":{"_account_id":30380,"name":"ZhouHeng","email":"zhouhenglc@inspur.com","username":"zhouhenglc"},"change_message_id":"97bb1ac0e407209480483b3a1ef4e40cb344c8fc","unresolved":false,"context_lines":[{"line_number":31,"context_line":"# revision identifiers, used by Alembic."},{"line_number":32,"context_line":"revision \u003d \u0027f010820fc498\u0027"},{"line_number":33,"context_line":"down_revision \u003d \u0027I38991de2b4\u0027"},{"line_number":34,"context_line":"depends_on \u003d (\u00277d9d8eeec6ad\u0027,)"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"quotas \u003d sa.Table("}],"source_content_type":"text/x-python","patch_set":10,"id":"1f621f24_d3fe34ad","line":34,"range":{"start_line":34,"start_character":15,"end_line":34,"end_character":27},"in_reply_to":"3f65232a_d51fe16d","updated":"2020-10-28 05:41:03.000000000","message":"this is a must, project_id is named tenant_id at the beginning of creating the table `quotas`.  we should migration after renamed, otherwise would report project not found.","commit_id":"210f0d5a2d7277a059b07c9ef7d765ead3075a04"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"1ef52b6ac939e5a1535658b1cd27b512f6fc3025","unresolved":false,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"class DuplicateQuotas(exceptions.Conflict):"},{"line_number":44,"context_line":"    message \u003d _(\"Duplicate Quotas is created for resource(s) %(resources)s. \""},{"line_number":45,"context_line":"                \"Database cannot be upgraded. Please, remove all duplicates \""},{"line_number":46,"context_line":"                \"before upgrading the database.\")"},{"line_number":47,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"3f65232a_352f35a2","line":44,"range":{"start_line":44,"start_character":34,"end_line":44,"end_character":36},"updated":"2020-10-28 05:02:26.000000000","message":"nit: are","commit_id":"210f0d5a2d7277a059b07c9ef7d765ead3075a04"},{"author":{"_account_id":30380,"name":"ZhouHeng","email":"zhouhenglc@inspur.com","username":"zhouhenglc"},"change_message_id":"5b7eaf9ff3bda68221efe6c93940ee7881e6b94b","unresolved":false,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"class DuplicateQuotas(exceptions.Conflict):"},{"line_number":44,"context_line":"    message \u003d _(\"Duplicate Quotas is created for resource(s) %(resources)s. \""},{"line_number":45,"context_line":"                \"Database cannot be upgraded. Please, remove all duplicates \""},{"line_number":46,"context_line":"                \"before upgrading the database.\")"},{"line_number":47,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"1f621f24_138eec2d","line":44,"range":{"start_line":44,"start_character":34,"end_line":44,"end_character":36},"in_reply_to":"3f65232a_352f35a2","updated":"2020-10-28 06:01:54.000000000","message":"Done","commit_id":"210f0d5a2d7277a059b07c9ef7d765ead3075a04"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"1ef52b6ac939e5a1535658b1cd27b512f6fc3025","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    query \u003d (session.query(quotas.c.project_id, quotas.c.resource)"},{"line_number":55,"context_line":"             .group_by(quotas.c.project_id, quotas.c.resource)"},{"line_number":56,"context_line":"             .having(sa.func.count() \u003e 1)).all()"},{"line_number":57,"context_line":"    return [(q[0], q[1]) for q in query]"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"def check_sanity(connection):"}],"source_content_type":"text/x-python","patch_set":10,"id":"1f621f24_d318f476","line":57,"range":{"start_line":57,"start_character":4,"end_line":57,"end_character":40},"updated":"2020-10-28 05:02:26.000000000","message":"nit: isn\u0027t query in needed form already (after .all())?","commit_id":"210f0d5a2d7277a059b07c9ef7d765ead3075a04"},{"author":{"_account_id":30380,"name":"ZhouHeng","email":"zhouhenglc@inspur.com","username":"zhouhenglc"},"change_message_id":"5b7eaf9ff3bda68221efe6c93940ee7881e6b94b","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    query \u003d (session.query(quotas.c.project_id, quotas.c.resource)"},{"line_number":55,"context_line":"             .group_by(quotas.c.project_id, quotas.c.resource)"},{"line_number":56,"context_line":"             .having(sa.func.count() \u003e 1)).all()"},{"line_number":57,"context_line":"    return [(q[0], q[1]) for q in query]"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"def check_sanity(connection):"}],"source_content_type":"text/x-python","patch_set":10,"id":"1f621f24_7383e005","line":57,"range":{"start_line":57,"start_character":4,"end_line":57,"end_character":40},"in_reply_to":"1f621f24_d318f476","updated":"2020-10-28 06:01:54.000000000","message":"Done","commit_id":"210f0d5a2d7277a059b07c9ef7d765ead3075a04"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"19e5d35e9729462de2541c393864a2d74e61d0de","unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":"class DuplicateQuotas(exceptions.Conflict):"},{"line_number":44,"context_line":"    message \u003d _(\"Duplicate Quotas are created for resource(s) %(resources)s.\""},{"line_number":45,"context_line":"                \" Database cannot be upgraded. Please, remove all duplicates \""},{"line_number":46,"context_line":"                \"before upgrading the database.\")"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"1f621f24_426263d9","line":45,"range":{"start_line":45,"start_character":17,"end_line":45,"end_character":18},"updated":"2020-11-16 21:42:18.000000000","message":"nitty nit: this space should be moved to the end of the line above.","commit_id":"c8c1daa514d34ff6e7b24ba9f25e3ebdf6300240"}],"neutron/db/quota/models.py":[{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"b875337bbdae3047349a623226616ffd9ae499a1","unresolved":false,"context_lines":[{"line_number":44,"context_line":"    If there is no row for a given tenant id and resource, then the"},{"line_number":45,"context_line":"    default for the deployment is used."},{"line_number":46,"context_line":"    \"\"\""},{"line_number":47,"context_line":"    __table_args__ \u003d (sa.UniqueConstraint("},{"line_number":48,"context_line":"        \u0027project_id\u0027,"},{"line_number":49,"context_line":"        \u0027resource\u0027,"},{"line_number":50,"context_line":"        name\u003d\u0027uniq_quotas0project_id0resource\u0027),"},{"line_number":51,"context_line":"    )"},{"line_number":52,"context_line":"    resource \u003d sa.Column(sa.String(255))"},{"line_number":53,"context_line":"    limit \u003d sa.Column(sa.Integer)"},{"line_number":54,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9f560f44_b4f0b9ff","line":51,"range":{"start_line":47,"start_character":4,"end_line":51,"end_character":5},"updated":"2020-08-28 13:40:04.000000000","message":"please place this after columns definition","commit_id":"c26939d894639a1cc5b67d7712f5d0c7e7afaf3a"},{"author":{"_account_id":30380,"name":"ZhouHeng","email":"zhouhenglc@inspur.com","username":"zhouhenglc"},"change_message_id":"be7057ba275590de037be3b522ffbf1f8dd46966","unresolved":false,"context_lines":[{"line_number":44,"context_line":"    If there is no row for a given tenant id and resource, then the"},{"line_number":45,"context_line":"    default for the deployment is used."},{"line_number":46,"context_line":"    \"\"\""},{"line_number":47,"context_line":"    __table_args__ \u003d (sa.UniqueConstraint("},{"line_number":48,"context_line":"        \u0027project_id\u0027,"},{"line_number":49,"context_line":"        \u0027resource\u0027,"},{"line_number":50,"context_line":"        name\u003d\u0027uniq_quotas0project_id0resource\u0027),"},{"line_number":51,"context_line":"    )"},{"line_number":52,"context_line":"    resource \u003d sa.Column(sa.String(255))"},{"line_number":53,"context_line":"    limit \u003d sa.Column(sa.Integer)"},{"line_number":54,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9f560f44_63c020e2","line":51,"range":{"start_line":47,"start_character":4,"end_line":51,"end_character":5},"in_reply_to":"9f560f44_b4f0b9ff","updated":"2020-08-29 02:14:25.000000000","message":"Done","commit_id":"c26939d894639a1cc5b67d7712f5d0c7e7afaf3a"}]}
