)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6282,"name":"Wu Wenxiang","email":"wu.wenxiang@algoblu.com","username":"wu-wenxiang"},"change_message_id":"27edf1eb2eae49d84c7820268099e8d0f9d9df2b","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"ModelsMigrationsSync: Add check for foreign keys"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Add method that checks that foreign keys in models  are synchonized"},{"line_number":10,"context_line":"with foreign keys that are created in database."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: I4a776da0f53a79218ed4b111cac33b37d264fa1b"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":12,"id":"fa98f980_110f1889","line":9,"updated":"2014-09-04 22:11:20.000000000","message":"mistake spaces between \"models\" \u0026 \"are\" :)","commit_id":"d5ac4fc73b3e67c8dc87ce60cac290d8f48848d0"}],"oslo/db/sqlalchemy/test_migrations.py":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"1b5fe2ee40bfe8fdd930e14da165f000dbf87534","unresolved":false,"context_lines":[{"line_number":386,"context_line":"            for table in tbs:"},{"line_number":387,"context_line":"                conn.execute(schema.DropTable(table))"},{"line_number":388,"context_line":""},{"line_number":389,"context_line":"    def check_foreign_keys(self, metadata, bind):"},{"line_number":390,"context_line":"        # This methods checks foreign keys that tables contain in models with"},{"line_number":391,"context_line":"        # foreign keys that are in db."},{"line_number":392,"context_line":"        diff \u003d []"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_1d928657","line":389,"updated":"2014-09-01 08:11:30.000000000","message":"nit: can we add a docstring describing the format of the return value?","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"ea260f6de81dace9edb7d6054cb78fd78fda17fd","unresolved":false,"context_lines":[{"line_number":386,"context_line":"            for table in tbs:"},{"line_number":387,"context_line":"                conn.execute(schema.DropTable(table))"},{"line_number":388,"context_line":""},{"line_number":389,"context_line":"    def check_foreign_keys(self, metadata, bind):"},{"line_number":390,"context_line":"        # This methods checks foreign keys that tables contain in models with"},{"line_number":391,"context_line":"        # foreign keys that are in db."},{"line_number":392,"context_line":"        diff \u003d []"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_2cc4763f","line":389,"in_reply_to":"fa98f980_1d928657","updated":"2014-09-01 11:15:37.000000000","message":"done","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"1b5fe2ee40bfe8fdd930e14da165f000dbf87534","unresolved":false,"context_lines":[{"line_number":410,"context_line":"            LOG.info(\"db key found \" + str(fk_db_set))"},{"line_number":411,"context_line":"            LOG.info(\"model key found \" + str(fk_models_set))"},{"line_number":412,"context_line":"            for key in (fk_db_set - fk_models_set):"},{"line_number":413,"context_line":"                diff.append((\u0027drop_key\u0027, fk_db[key], table))"},{"line_number":414,"context_line":"                LOG.info((\"Detected removed foreign key %(fk)r on \""},{"line_number":415,"context_line":"                          \"table %(table)r\"), {\u0027fk\u0027: fk_db[key],"},{"line_number":416,"context_line":"                                               \u0027table\u0027: table})"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_605f650f","line":413,"updated":"2014-09-01 08:11:30.000000000","message":"if I\u0027m not missing something, the only information we mention in diff is the FK name, shouldn\u0027t we also add the information about constrained columns, the referred table and referred columns?","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"ea260f6de81dace9edb7d6054cb78fd78fda17fd","unresolved":false,"context_lines":[{"line_number":410,"context_line":"            LOG.info(\"db key found \" + str(fk_db_set))"},{"line_number":411,"context_line":"            LOG.info(\"model key found \" + str(fk_models_set))"},{"line_number":412,"context_line":"            for key in (fk_db_set - fk_models_set):"},{"line_number":413,"context_line":"                diff.append((\u0027drop_key\u0027, fk_db[key], table))"},{"line_number":414,"context_line":"                LOG.info((\"Detected removed foreign key %(fk)r on \""},{"line_number":415,"context_line":"                          \"table %(table)r\"), {\u0027fk\u0027: fk_db[key],"},{"line_number":416,"context_line":"                                               \u0027table\u0027: table})"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_2e546b53","line":413,"in_reply_to":"fa98f980_605f650f","updated":"2014-09-01 11:15:37.000000000","message":"done","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"1b5fe2ee40bfe8fdd930e14da165f000dbf87534","unresolved":false,"context_lines":[{"line_number":415,"context_line":"                          \"table %(table)r\"), {\u0027fk\u0027: fk_db[key],"},{"line_number":416,"context_line":"                                               \u0027table\u0027: table})"},{"line_number":417,"context_line":"            for key in (fk_models_set - fk_db_set):"},{"line_number":418,"context_line":"                diff.append((\u0027add_key\u0027, fk_models[key]))"},{"line_number":419,"context_line":"                LOG.info(("},{"line_number":420,"context_line":"                    \"Detected added foreign key for column %(fk)r on table \""},{"line_number":421,"context_line":"                    \"%(table)r\"), {\u0027fk\u0027: fk_models[key].column.name,"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_a0a06df5","line":418,"updated":"2014-09-01 08:11:30.000000000","message":"information ditto","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"ea260f6de81dace9edb7d6054cb78fd78fda17fd","unresolved":false,"context_lines":[{"line_number":415,"context_line":"                          \"table %(table)r\"), {\u0027fk\u0027: fk_db[key],"},{"line_number":416,"context_line":"                                               \u0027table\u0027: table})"},{"line_number":417,"context_line":"            for key in (fk_models_set - fk_db_set):"},{"line_number":418,"context_line":"                diff.append((\u0027add_key\u0027, fk_models[key]))"},{"line_number":419,"context_line":"                LOG.info(("},{"line_number":420,"context_line":"                    \"Detected added foreign key for column %(fk)r on table \""},{"line_number":421,"context_line":"                    \"%(table)r\"), {\u0027fk\u0027: fk_models[key].column.name,"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_6e4e73c3","line":418,"in_reply_to":"fa98f980_a0a06df5","updated":"2014-09-01 11:15:37.000000000","message":"done","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"1b5fe2ee40bfe8fdd930e14da165f000dbf87534","unresolved":false,"context_lines":[{"line_number":422,"context_line":"                                   \u0027table\u0027: table})"},{"line_number":423,"context_line":"        return diff"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"    def _get_fk_info_db(self, fk):"},{"line_number":426,"context_line":"        return (tuple(fk[\u0027constrained_columns\u0027]), fk[\u0027referred_table\u0027],"},{"line_number":427,"context_line":"                tuple(fk[\u0027referred_columns\u0027]))"},{"line_number":428,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_5daa4e71","line":425,"updated":"2014-09-01 08:11:30.000000000","message":"nit: this should probably be either a helper \u0027private\u0027 function or a static method (as it doesn\u0027t use self)","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"ea260f6de81dace9edb7d6054cb78fd78fda17fd","unresolved":false,"context_lines":[{"line_number":422,"context_line":"                                   \u0027table\u0027: table})"},{"line_number":423,"context_line":"        return diff"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"    def _get_fk_info_db(self, fk):"},{"line_number":426,"context_line":"        return (tuple(fk[\u0027constrained_columns\u0027]), fk[\u0027referred_table\u0027],"},{"line_number":427,"context_line":"                tuple(fk[\u0027referred_columns\u0027]))"},{"line_number":428,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_aec77b11","line":425,"in_reply_to":"fa98f980_5daa4e71","updated":"2014-09-01 11:15:37.000000000","message":"done","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"1b5fe2ee40bfe8fdd930e14da165f000dbf87534","unresolved":false,"context_lines":[{"line_number":423,"context_line":"        return diff"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"    def _get_fk_info_db(self, fk):"},{"line_number":426,"context_line":"        return (tuple(fk[\u0027constrained_columns\u0027]), fk[\u0027referred_table\u0027],"},{"line_number":427,"context_line":"                tuple(fk[\u0027referred_columns\u0027]))"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    def _get_fk_info_from_model(self, fk):"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_3df10ace","line":426,"updated":"2014-09-01 08:11:30.000000000","message":"nit: in order to make this more readable we could use named tuples here (so that we could access tuple elements by name rather than by index)","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"ea260f6de81dace9edb7d6054cb78fd78fda17fd","unresolved":false,"context_lines":[{"line_number":423,"context_line":"        return diff"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"    def _get_fk_info_db(self, fk):"},{"line_number":426,"context_line":"        return (tuple(fk[\u0027constrained_columns\u0027]), fk[\u0027referred_table\u0027],"},{"line_number":427,"context_line":"                tuple(fk[\u0027referred_columns\u0027]))"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    def _get_fk_info_from_model(self, fk):"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_eed183ce","line":426,"in_reply_to":"fa98f980_3df10ace","updated":"2014-09-01 11:15:37.000000000","message":"done","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"1b5fe2ee40bfe8fdd930e14da165f000dbf87534","unresolved":false,"context_lines":[{"line_number":426,"context_line":"        return (tuple(fk[\u0027constrained_columns\u0027]), fk[\u0027referred_table\u0027],"},{"line_number":427,"context_line":"                tuple(fk[\u0027referred_columns\u0027]))"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    def _get_fk_info_from_model(self, fk):"},{"line_number":430,"context_line":"        return ((fk.parent.name,), fk.column.table.name, (fk.column.name,))"},{"line_number":431,"context_line":""},{"line_number":432,"context_line":"    def test_models_sync(self):"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_9dbbd6c3","line":429,"updated":"2014-09-01 08:11:30.000000000","message":"nit: helper function ditto","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"ea260f6de81dace9edb7d6054cb78fd78fda17fd","unresolved":false,"context_lines":[{"line_number":426,"context_line":"        return (tuple(fk[\u0027constrained_columns\u0027]), fk[\u0027referred_table\u0027],"},{"line_number":427,"context_line":"                tuple(fk[\u0027referred_columns\u0027]))"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    def _get_fk_info_from_model(self, fk):"},{"line_number":430,"context_line":"        return ((fk.parent.name,), fk.column.table.name, (fk.column.name,))"},{"line_number":431,"context_line":""},{"line_number":432,"context_line":"    def test_models_sync(self):"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_54da2079","line":429,"in_reply_to":"fa98f980_9dbbd6c3","updated":"2014-09-01 11:15:37.000000000","message":"done","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"1b5fe2ee40bfe8fdd930e14da165f000dbf87534","unresolved":false,"context_lines":[{"line_number":427,"context_line":"                tuple(fk[\u0027referred_columns\u0027]))"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    def _get_fk_info_from_model(self, fk):"},{"line_number":430,"context_line":"        return ((fk.parent.name,), fk.column.table.name, (fk.column.name,))"},{"line_number":431,"context_line":""},{"line_number":432,"context_line":"    def test_models_sync(self):"},{"line_number":433,"context_line":"        # recent versions of sqlalchemy and alembic are needed for running of"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_5deeceed","line":430,"updated":"2014-09-01 08:11:30.000000000","message":"nit: named tuple ditto","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"ea260f6de81dace9edb7d6054cb78fd78fda17fd","unresolved":false,"context_lines":[{"line_number":427,"context_line":"                tuple(fk[\u0027referred_columns\u0027]))"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    def _get_fk_info_from_model(self, fk):"},{"line_number":430,"context_line":"        return ((fk.parent.name,), fk.column.table.name, (fk.column.name,))"},{"line_number":431,"context_line":""},{"line_number":432,"context_line":"    def test_models_sync(self):"},{"line_number":433,"context_line":"        # recent versions of sqlalchemy and alembic are needed for running of"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_4ed8cfef","line":430,"in_reply_to":"fa98f980_5deeceed","updated":"2014-09-01 11:15:37.000000000","message":"done","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"1b5fe2ee40bfe8fdd930e14da165f000dbf87534","unresolved":false,"context_lines":[{"line_number":457,"context_line":"                                                          self.get_metadata())"},{"line_number":458,"context_line":"            diff2 \u003d self.check_foreign_keys(self.get_metadata(),"},{"line_number":459,"context_line":"                                            self.get_engine())"},{"line_number":460,"context_line":"            LOG.info(\"Test\" + str(diff2))"},{"line_number":461,"context_line":"            diff \u003d diff1 + diff2"},{"line_number":462,"context_line":"            if diff:"},{"line_number":463,"context_line":"                msg \u003d pprint.pformat(diff, indent\u003d2, width\u003d20)"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_bd0c1a96","line":460,"updated":"2014-09-01 08:11:30.000000000","message":"nit: debug log? :)","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"ea260f6de81dace9edb7d6054cb78fd78fda17fd","unresolved":false,"context_lines":[{"line_number":457,"context_line":"                                                          self.get_metadata())"},{"line_number":458,"context_line":"            diff2 \u003d self.check_foreign_keys(self.get_metadata(),"},{"line_number":459,"context_line":"                                            self.get_engine())"},{"line_number":460,"context_line":"            LOG.info(\"Test\" + str(diff2))"},{"line_number":461,"context_line":"            diff \u003d diff1 + diff2"},{"line_number":462,"context_line":"            if diff:"},{"line_number":463,"context_line":"                msg \u003d pprint.pformat(diff, indent\u003d2, width\u003d20)"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_34411c3a","line":460,"in_reply_to":"fa98f980_bd0c1a96","updated":"2014-09-01 11:15:37.000000000","message":"yes, remove this :)","commit_id":"0cb38f2052575e0c8ed7912796c6b395379e0b47"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"852837a82bdd251dcf27e73de3987f83d2affb9e","unresolved":false,"context_lines":[{"line_number":387,"context_line":"            for table in tbs:"},{"line_number":388,"context_line":"                conn.execute(schema.DropTable(table))"},{"line_number":389,"context_line":""},{"line_number":390,"context_line":"    _FKInfo \u003d collections.namedtuple(\u0027fk_info\u0027, [\u0027constrained_columns\u0027,"},{"line_number":391,"context_line":"                                                 \u0027referred_table\u0027,"},{"line_number":392,"context_line":"                                                 \u0027referred_columns\u0027])"},{"line_number":393,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"fa98f980_53d75d23","line":390,"updated":"2014-09-02 08:05:27.000000000","message":"nit: let\u0027s make it a public attribute","commit_id":"fb131a020c8bbe4613b0ffeef7831c87051b8371"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"e4f428308b40586a3545331b5851e6d6ea5a9c64","unresolved":false,"context_lines":[{"line_number":387,"context_line":"            for table in tbs:"},{"line_number":388,"context_line":"                conn.execute(schema.DropTable(table))"},{"line_number":389,"context_line":""},{"line_number":390,"context_line":"    _FKInfo \u003d collections.namedtuple(\u0027fk_info\u0027, [\u0027constrained_columns\u0027,"},{"line_number":391,"context_line":"                                                 \u0027referred_table\u0027,"},{"line_number":392,"context_line":"                                                 \u0027referred_columns\u0027])"},{"line_number":393,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"fa98f980_4ebed2d5","line":390,"in_reply_to":"fa98f980_53d75d23","updated":"2014-09-02 08:44:45.000000000","message":"Done","commit_id":"fb131a020c8bbe4613b0ffeef7831c87051b8371"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"852837a82bdd251dcf27e73de3987f83d2affb9e","unresolved":false,"context_lines":[{"line_number":398,"context_line":"         * should be a new key added or removed existing,"},{"line_number":399,"context_line":"         * name of that key,"},{"line_number":400,"context_line":"         * source table,"},{"line_number":401,"context_line":"         * referent table,"},{"line_number":402,"context_line":"         * constrained columns,"},{"line_number":403,"context_line":"         * referent columns"},{"line_number":404,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"fa98f980_33a2d9ae","line":401,"updated":"2014-09-02 08:05:27.000000000","message":"nit: referred?","commit_id":"fb131a020c8bbe4613b0ffeef7831c87051b8371"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"e4f428308b40586a3545331b5851e6d6ea5a9c64","unresolved":false,"context_lines":[{"line_number":398,"context_line":"         * should be a new key added or removed existing,"},{"line_number":399,"context_line":"         * name of that key,"},{"line_number":400,"context_line":"         * source table,"},{"line_number":401,"context_line":"         * referent table,"},{"line_number":402,"context_line":"         * constrained columns,"},{"line_number":403,"context_line":"         * referent columns"},{"line_number":404,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"fa98f980_aece5e81","line":401,"in_reply_to":"fa98f980_33a2d9ae","updated":"2014-09-02 08:44:45.000000000","message":"Done","commit_id":"fb131a020c8bbe4613b0ffeef7831c87051b8371"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"852837a82bdd251dcf27e73de3987f83d2affb9e","unresolved":false,"context_lines":[{"line_number":400,"context_line":"         * source table,"},{"line_number":401,"context_line":"         * referent table,"},{"line_number":402,"context_line":"         * constrained columns,"},{"line_number":403,"context_line":"         * referent columns"},{"line_number":404,"context_line":""},{"line_number":405,"context_line":"         Output:"},{"line_number":406,"context_line":"         [ ( \u0027drop_key\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"fa98f980_73ac61a1","line":403,"updated":"2014-09-02 08:05:27.000000000","message":"nit: referred ditto","commit_id":"fb131a020c8bbe4613b0ffeef7831c87051b8371"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"e4f428308b40586a3545331b5851e6d6ea5a9c64","unresolved":false,"context_lines":[{"line_number":400,"context_line":"         * source table,"},{"line_number":401,"context_line":"         * referent table,"},{"line_number":402,"context_line":"         * constrained columns,"},{"line_number":403,"context_line":"         * referent columns"},{"line_number":404,"context_line":""},{"line_number":405,"context_line":"         Output:"},{"line_number":406,"context_line":"         [ ( \u0027drop_key\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"fa98f980_cec9e27a","line":403,"in_reply_to":"fa98f980_73ac61a1","updated":"2014-09-02 08:44:45.000000000","message":"done","commit_id":"fb131a020c8bbe4613b0ffeef7831c87051b8371"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"852837a82bdd251dcf27e73de3987f83d2affb9e","unresolved":false,"context_lines":[{"line_number":402,"context_line":"         * constrained columns,"},{"line_number":403,"context_line":"         * referent columns"},{"line_number":404,"context_line":""},{"line_number":405,"context_line":"         Output:"},{"line_number":406,"context_line":"         [ ( \u0027drop_key\u0027,"},{"line_number":407,"context_line":"            \u0027testtbl_fk_check_fkey\u0027,"},{"line_number":408,"context_line":"            \u0027testtbl\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"fa98f980_93e1c500","line":405,"updated":"2014-09-02 08:05:27.000000000","message":"nit: please add an empty line here","commit_id":"fb131a020c8bbe4613b0ffeef7831c87051b8371"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"e4f428308b40586a3545331b5851e6d6ea5a9c64","unresolved":false,"context_lines":[{"line_number":402,"context_line":"         * constrained columns,"},{"line_number":403,"context_line":"         * referent columns"},{"line_number":404,"context_line":""},{"line_number":405,"context_line":"         Output:"},{"line_number":406,"context_line":"         [ ( \u0027drop_key\u0027,"},{"line_number":407,"context_line":"            \u0027testtbl_fk_check_fkey\u0027,"},{"line_number":408,"context_line":"            \u0027testtbl\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"fa98f980_6eac76a1","line":405,"in_reply_to":"fa98f980_93e1c500","updated":"2014-09-02 08:44:45.000000000","message":"done","commit_id":"fb131a020c8bbe4613b0ffeef7831c87051b8371"},{"author":{"_account_id":12363,"name":"Oleksii Chuprykov","email":"a.chuprikoff@gmail.com","username":"ochuprykov"},"change_message_id":"a1851b108dc0558744e2c65a65bfb3c831daebe5","unresolved":false,"context_lines":[{"line_number":402,"context_line":"         * constrained columns,"},{"line_number":403,"context_line":"         * referred columns"},{"line_number":404,"context_line":""},{"line_number":405,"context_line":"         Output:"},{"line_number":406,"context_line":""},{"line_number":407,"context_line":"         [ ( \u0027drop_key\u0027,"},{"line_number":408,"context_line":"            \u0027testtbl_fk_check_fkey\u0027,"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa98f980_f49d7b5a","line":405,"updated":"2014-09-02 20:34:21.000000000","message":"I think output block is rendered incorrectly, see http://docs-draft.openstack.org/38/116238/11/check/gate-oslo.db-docs/b48f85b/doc/build/html/api/oslo.db.sqlalchemy.test_migrations.html#module-oslo.db.sqlalchemy.test_migrations","commit_id":"c50efed597b8f08f1dc6a74e6ae6cee8ceab1577"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"f95d73860083ed45a4cd9398cc68022d76264a46","unresolved":false,"context_lines":[{"line_number":402,"context_line":"         * constrained columns,"},{"line_number":403,"context_line":"         * referred columns"},{"line_number":404,"context_line":""},{"line_number":405,"context_line":"         Output:"},{"line_number":406,"context_line":""},{"line_number":407,"context_line":"         [ ( \u0027drop_key\u0027,"},{"line_number":408,"context_line":"            \u0027testtbl_fk_check_fkey\u0027,"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa98f980_777171df","line":405,"in_reply_to":"fa98f980_f49d7b5a","updated":"2014-09-03 13:24:17.000000000","message":"done","commit_id":"c50efed597b8f08f1dc6a74e6ae6cee8ceab1577"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"d65dce3d6d2bab7442deddab6848e6b34c71fda3","unresolved":false,"context_lines":[{"line_number":449,"context_line":"                           fk[\u0027referred_table\u0027],"},{"line_number":450,"context_line":"                           tuple(fk[\u0027referred_columns\u0027]))"},{"line_number":451,"context_line":""},{"line_number":452,"context_line":"    def _get_fk_info_from_model(self, fk):"},{"line_number":453,"context_line":"        return self.FKInfo((fk.parent.name,), fk.column.table.name,"},{"line_number":454,"context_line":"                           (fk.column.name,))"},{"line_number":455,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"fa98f980_66f48f87","line":452,"updated":"2014-09-02 14:14:55.000000000","message":"I think we are missing one edge case here ignoring composite foreign keys. I\u0027m not sure we use them anywhere in consuming openstack projects, but still, it\u0027d be nice to have support for those.\n\nWe should probably analyze http://docs.sqlalchemy.org/en/rel_0_9/core/constraints.html#sqlalchemy.schema.ForeignKeyConstraint instances from table.constraints rather than table.foreign_keys to get that info.","commit_id":"c50efed597b8f08f1dc6a74e6ae6cee8ceab1577"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"f95d73860083ed45a4cd9398cc68022d76264a46","unresolved":false,"context_lines":[{"line_number":449,"context_line":"                           fk[\u0027referred_table\u0027],"},{"line_number":450,"context_line":"                           tuple(fk[\u0027referred_columns\u0027]))"},{"line_number":451,"context_line":""},{"line_number":452,"context_line":"    def _get_fk_info_from_model(self, fk):"},{"line_number":453,"context_line":"        return self.FKInfo((fk.parent.name,), fk.column.table.name,"},{"line_number":454,"context_line":"                           (fk.column.name,))"},{"line_number":455,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"fa98f980_ba402035","line":452,"in_reply_to":"fa98f980_66f48f87","updated":"2014-09-03 13:24:17.000000000","message":"I think that could be added separately or even in alembic. I tried to use table.constraints instead of table.foreign_keys but get some strange results, so this need deep investigation, so I hope it is not necessary to make this for this change to be merged.","commit_id":"c50efed597b8f08f1dc6a74e6ae6cee8ceab1577"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"9f7b01a0ca2919952ef59aded1897b0b107e3f57","unresolved":false,"context_lines":[{"line_number":434,"context_line":"    def check_foreign_keys(self, metadata, bind):"},{"line_number":435,"context_line":"        \"\"\"Compare foreign keys between model and db table."},{"line_number":436,"context_line":""},{"line_number":437,"context_line":"        Returns a list that contains information about:"},{"line_number":438,"context_line":"         * should be a new key added or removed existing,"},{"line_number":439,"context_line":"         * name of that key,"},{"line_number":440,"context_line":"         * source table,"}],"source_content_type":"text/x-python","patch_set":14,"id":"fa98f980_5e2cdd4a","line":437,"updated":"2014-09-09 11:49:07.000000000","message":"reST has standard directive `:returns:`.","commit_id":"a48e233e18b768f3d96be0cd9f650bc6d7856316"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"5522118aa381dbccc170b3f6d59570e2eafdf23f","unresolved":false,"context_lines":[{"line_number":434,"context_line":"    def check_foreign_keys(self, metadata, bind):"},{"line_number":435,"context_line":"        \"\"\"Compare foreign keys between model and db table."},{"line_number":436,"context_line":""},{"line_number":437,"context_line":"        Returns a list that contains information about:"},{"line_number":438,"context_line":"         * should be a new key added or removed existing,"},{"line_number":439,"context_line":"         * name of that key,"},{"line_number":440,"context_line":"         * source table,"}],"source_content_type":"text/x-python","patch_set":14,"id":"fa98f980_e4dc1e77","line":437,"in_reply_to":"fa98f980_5e2cdd4a","updated":"2014-09-09 12:16:50.000000000","message":"Please, turn it into\n\n    :returns:\n\nAnd +1 will come from me.","commit_id":"a48e233e18b768f3d96be0cd9f650bc6d7856316"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"9f7b01a0ca2919952ef59aded1897b0b107e3f57","unresolved":false,"context_lines":[{"line_number":473,"context_line":"            fk_models_set \u003d set(fk_models.keys())"},{"line_number":474,"context_line":"            for key in (fk_db_set - fk_models_set):"},{"line_number":475,"context_line":"                diff.append((\u0027drop_key\u0027, fk_db[key], table, key))"},{"line_number":476,"context_line":"                LOG.info((\"Detected removed foreign key %(fk)r on \""},{"line_number":477,"context_line":"                          \"table %(table)r\"), {\u0027fk\u0027: fk_db[key],"},{"line_number":478,"context_line":"                                               \u0027table\u0027: table})"},{"line_number":479,"context_line":"            for key in (fk_models_set - fk_db_set):"}],"source_content_type":"text/x-python","patch_set":14,"id":"fa98f980_7e8b611e","line":476,"updated":"2014-09-09 11:49:07.000000000","message":"The formulation is not clear to me. I\u0027d rather phrase it like this: In the table \u003c\u003e detected a foreign key which absent in the model \u003c\u003e. And vice versa.","commit_id":"a48e233e18b768f3d96be0cd9f650bc6d7856316"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"9c449484a0d5d1e0d780f16d6ce1e7677a28c4af","unresolved":false,"context_lines":[{"line_number":473,"context_line":"            fk_models_set \u003d set(fk_models.keys())"},{"line_number":474,"context_line":"            for key in (fk_db_set - fk_models_set):"},{"line_number":475,"context_line":"                diff.append((\u0027drop_key\u0027, fk_db[key], table, key))"},{"line_number":476,"context_line":"                LOG.info((\"Detected removed foreign key %(fk)r on \""},{"line_number":477,"context_line":"                          \"table %(table)r\"), {\u0027fk\u0027: fk_db[key],"},{"line_number":478,"context_line":"                                               \u0027table\u0027: table})"},{"line_number":479,"context_line":"            for key in (fk_models_set - fk_db_set):"}],"source_content_type":"text/x-python","patch_set":14,"id":"fa98f980_d9c9c75b","line":476,"in_reply_to":"fa98f980_7e8b611e","updated":"2014-09-09 11:58:37.000000000","message":"This is the same format as used alembic \"Detected added table\", \"Detected server default on column\" etc. I think that for equality of logs it should be the same.","commit_id":"a48e233e18b768f3d96be0cd9f650bc6d7856316"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"5522118aa381dbccc170b3f6d59570e2eafdf23f","unresolved":false,"context_lines":[{"line_number":473,"context_line":"            fk_models_set \u003d set(fk_models.keys())"},{"line_number":474,"context_line":"            for key in (fk_db_set - fk_models_set):"},{"line_number":475,"context_line":"                diff.append((\u0027drop_key\u0027, fk_db[key], table, key))"},{"line_number":476,"context_line":"                LOG.info((\"Detected removed foreign key %(fk)r on \""},{"line_number":477,"context_line":"                          \"table %(table)r\"), {\u0027fk\u0027: fk_db[key],"},{"line_number":478,"context_line":"                                               \u0027table\u0027: table})"},{"line_number":479,"context_line":"            for key in (fk_models_set - fk_db_set):"}],"source_content_type":"text/x-python","patch_set":14,"id":"fa98f980_0491229a","line":476,"in_reply_to":"fa98f980_d9c9c75b","updated":"2014-09-09 12:16:50.000000000","message":"I\u0027m good with it.","commit_id":"a48e233e18b768f3d96be0cd9f650bc6d7856316"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"9f7b01a0ca2919952ef59aded1897b0b107e3f57","unresolved":false,"context_lines":[{"line_number":478,"context_line":"                                               \u0027table\u0027: table})"},{"line_number":479,"context_line":"            for key in (fk_models_set - fk_db_set):"},{"line_number":480,"context_line":"                diff.append((\u0027add_key\u0027, fk_models[key], key))"},{"line_number":481,"context_line":"                LOG.info(("},{"line_number":482,"context_line":"                    \"Detected added foreign key for column %(fk)r on table \""},{"line_number":483,"context_line":"                    \"%(table)r\"), {\u0027fk\u0027: fk_models[key].column.name,"},{"line_number":484,"context_line":"                                   \u0027table\u0027: table})"}],"source_content_type":"text/x-python","patch_set":14,"id":"fa98f980_be85c908","line":481,"updated":"2014-09-09 11:49:07.000000000","message":"ditto","commit_id":"a48e233e18b768f3d96be0cd9f650bc6d7856316"}],"tests/sqlalchemy/test_migrations.py":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"d65dce3d6d2bab7442deddab6848e6b34c71fda3","unresolved":false,"context_lines":[{"line_number":205,"context_line":"            eggs \u003d sa.Column(\u0027eggs\u0027, sa.DateTime)"},{"line_number":206,"context_line":"            foo \u003d sa.Column(\u0027foo\u0027, sa.Boolean,"},{"line_number":207,"context_line":"                            server_default\u003dsa.sql.expression.true())"},{"line_number":208,"context_line":"            fk_check \u003d sa.Column(\u0027fk_check\u0027, sa.String(36), nullable\u003dFalse)"},{"line_number":209,"context_line":"            bool_wo_default \u003d sa.Column(\u0027bool_wo_default\u0027, sa.Boolean)"},{"line_number":210,"context_line":"            bar \u003d sa.Column(\u0027bar\u0027, sa.Numeric(10, 5))"},{"line_number":211,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"fa98f980_46406ba5","line":208,"updated":"2014-09-02 14:14:55.000000000","message":"can we add a check for a composite FK here?","commit_id":"c50efed597b8f08f1dc6a74e6ae6cee8ceab1577"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"9f7b01a0ca2919952ef59aded1897b0b107e3f57","unresolved":false,"context_lines":[{"line_number":259,"context_line":"            sa.Column(\u0027fk_check\u0027, sa.String(36), nullable\u003dFalse),"},{"line_number":260,"context_line":"            sa.UniqueConstraint(\u0027spam\u0027, \u0027foo\u0027, name\u003d\u0027uniq_cons\u0027),"},{"line_number":261,"context_line":"            sa.ForeignKeyConstraint([\u0027fk_check\u0027], [\u0027table.fk_check\u0027]),"},{"line_number":262,"context_line":"            mysql_engine\u003d\u0027InnoDB\u0027"},{"line_number":263,"context_line":"        )"},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"        msg \u003d six.text_type(self.assertRaises(AssertionError,"}],"source_content_type":"text/x-python","patch_set":14,"id":"fa98f980_f9be8bff","line":262,"updated":"2014-09-09 11:49:07.000000000","message":"Doesn\u0027t it affect table with Postgres?","commit_id":"a48e233e18b768f3d96be0cd9f650bc6d7856316"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"9c449484a0d5d1e0d780f16d6ce1e7677a28c4af","unresolved":false,"context_lines":[{"line_number":259,"context_line":"            sa.Column(\u0027fk_check\u0027, sa.String(36), nullable\u003dFalse),"},{"line_number":260,"context_line":"            sa.UniqueConstraint(\u0027spam\u0027, \u0027foo\u0027, name\u003d\u0027uniq_cons\u0027),"},{"line_number":261,"context_line":"            sa.ForeignKeyConstraint([\u0027fk_check\u0027], [\u0027table.fk_check\u0027]),"},{"line_number":262,"context_line":"            mysql_engine\u003d\u0027InnoDB\u0027"},{"line_number":263,"context_line":"        )"},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"        msg \u003d six.text_type(self.assertRaises(AssertionError,"}],"source_content_type":"text/x-python","patch_set":14,"id":"fa98f980_99fe5f6a","line":262,"in_reply_to":"fa98f980_f9be8bff","updated":"2014-09-09 11:58:37.000000000","message":"No it doesn\u0027t.","commit_id":"a48e233e18b768f3d96be0cd9f650bc6d7856316"}]}
