)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"93e207490975bb8943c64432d43f8fa52afcbd2e","unresolved":false,"context_lines":[{"line_number":5,"context_line":"CommitDate: 2017-08-30 15:31:44 +0300"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add nb db migration mechanism"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This patch adds the nb db migration mechanism by providing a new"},{"line_number":10,"context_line":"command *df-db upgrade*"},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"For instance, unique_key is a new field for lswitch since [1], for the"},{"line_number":13,"context_line":"data that exists before [1]. It will not have unique_key, and will break"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":14,"id":"7f287b81_23b41135","line":10,"range":{"start_line":8,"start_character":0,"end_line":10,"end_character":23},"updated":"2017-09-03 07:28:07.000000000","message":"I think it\u0027s worth expanding the migration table to a collection of migration objects, containing the upgrade module name (and hash), date applied, and the other helpful information.","commit_id":"9755bbacf9c536309e9ee5714507b6bf666885c9"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"93e207490975bb8943c64432d43f8fa52afcbd2e","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This patch adds the nb db migration mechanism by providing a new"},{"line_number":10,"context_line":"command *df-db upgrade*"},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"For instance, unique_key is a new field for lswitch since [1], for the"},{"line_number":13,"context_line":"data that exists before [1]. It will not have unique_key, and will break"},{"line_number":14,"context_line":"the usecase of unique_key for lswitch."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"[1] https://review.openstack.org/#/c/394017/"},{"line_number":17,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":14,"id":"7f287b81_e3872961","line":14,"range":{"start_line":12,"start_character":0,"end_line":14,"end_character":38},"updated":"2017-09-03 07:28:07.000000000","message":"No longer relevant","commit_id":"9755bbacf9c536309e9ee5714507b6bf666885c9"},{"author":{"_account_id":6598,"name":"Berezovsky Irena","email":"irenab.dev@gmail.com","username":"irenab"},"change_message_id":"a638bd998c588b3ca680fe7fa2288c74b2aa51c5","unresolved":false,"context_lines":[{"line_number":5,"context_line":"CommitDate: 2017-09-18 10:18:15 +0300"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"[WIP] Add nb db migration mechanism"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"To be completed..."},{"line_number":10,"context_line":""},{"line_number":11,"context_line":"Change-Id: Ibe1f04c4e8c09a706b4160a2fd729deafb408752"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":19,"id":"5f2577a7_e2a675ab","line":8,"updated":"2017-09-18 08:55:46.000000000","message":"need to be updated","commit_id":"8b9ae65eba7c93f77c44e8144f91f327aac24a9d"},{"author":{"_account_id":6598,"name":"Berezovsky Irena","email":"irenab.dev@gmail.com","username":"irenab"},"change_message_id":"a638bd998c588b3ca680fe7fa2288c74b2aa51c5","unresolved":false,"context_lines":[{"line_number":7,"context_line":"[WIP] Add nb db migration mechanism"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"To be completed..."},{"line_number":10,"context_line":""},{"line_number":11,"context_line":"Change-Id: Ibe1f04c4e8c09a706b4160a2fd729deafb408752"},{"line_number":12,"context_line":"Closes-Bug: #1644111"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":19,"id":"5f2577a7_a7f63f62","line":10,"updated":"2017-09-18 08:55:46.000000000","message":"please change ownership or add co-author","commit_id":"8b9ae65eba7c93f77c44e8144f91f327aac24a9d"}],"dragonflow/cli/df_db.py":[{"author":{"_account_id":20287,"name":"hujie","email":"mike.hu@huawei.com","username":"hujie"},"change_message_id":"329cdbb0e30c45ab79a9e9a014e1bf6df2eb5ce2","unresolved":false,"context_lines":[{"line_number":247,"context_line":""},{"line_number":248,"context_line":"def add_db_upgrade_command(subparsers):"},{"line_number":249,"context_line":"    def handle(db_driver, args):"},{"line_number":250,"context_line":"        cur_version_num \u003d migration_common.get_current_db_version(db_driver)"},{"line_number":251,"context_line":"        all_versions \u003d migration_common.get_sorted_all_version_modules()"},{"line_number":252,"context_line":"        for version in all_versions:"},{"line_number":253,"context_line":"            if cur_version_num is not None:"},{"line_number":254,"context_line":"                if cur_version_num \u003e version.VERSION:"},{"line_number":255,"context_line":"                    continue"},{"line_number":256,"context_line":"                elif cur_version_num \u003d\u003d version.VERSION:"},{"line_number":257,"context_line":"                    print \"Current version %s: %s\" % (version.VERSION,"},{"line_number":258,"context_line":"                                                      version.DESCRIPTION)"},{"line_number":259,"context_line":"                    continue"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"            print \"Upgrade to version %s: %s\" % (version.VERSION,"},{"line_number":262,"context_line":"                                                 version.DESCRIPTION)"},{"line_number":263,"context_line":"            version.upgrade(db_driver)"},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"        migration_common.set_db_migration_metadata(db_driver, all_versions[-1])"},{"line_number":266,"context_line":""},{"line_number":267,"context_line":"    sub_parser \u003d subparsers.add_parser(\u0027upgrade\u0027,"},{"line_number":268,"context_line":"                                       help\u003d\"Upgrade the Northbound Database.\")"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a6eadb0_3dfde13a","line":265,"range":{"start_line":250,"start_character":8,"end_line":265,"end_character":79},"updated":"2016-12-13 14:20:34.000000000","message":"it seems the code is similar with above, could they be merged?","commit_id":"62cc29f310a68d56ed26e51ed7c8eb0fc9fad370"},{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"fbd3b9e9894ee317314cc5ad5180e021db844672","unresolved":false,"context_lines":[{"line_number":247,"context_line":""},{"line_number":248,"context_line":"def add_db_upgrade_command(subparsers):"},{"line_number":249,"context_line":"    def handle(db_driver, args):"},{"line_number":250,"context_line":"        cur_version_num \u003d migration_common.get_current_db_version(db_driver)"},{"line_number":251,"context_line":"        all_versions \u003d migration_common.get_sorted_all_version_modules()"},{"line_number":252,"context_line":"        for version in all_versions:"},{"line_number":253,"context_line":"            if cur_version_num is not None:"},{"line_number":254,"context_line":"                if cur_version_num \u003e version.VERSION:"},{"line_number":255,"context_line":"                    continue"},{"line_number":256,"context_line":"                elif cur_version_num \u003d\u003d version.VERSION:"},{"line_number":257,"context_line":"                    print \"Current version %s: %s\" % (version.VERSION,"},{"line_number":258,"context_line":"                                                      version.DESCRIPTION)"},{"line_number":259,"context_line":"                    continue"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"            print \"Upgrade to version %s: %s\" % (version.VERSION,"},{"line_number":262,"context_line":"                                                 version.DESCRIPTION)"},{"line_number":263,"context_line":"            version.upgrade(db_driver)"},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"        migration_common.set_db_migration_metadata(db_driver, all_versions[-1])"},{"line_number":266,"context_line":""},{"line_number":267,"context_line":"    sub_parser \u003d subparsers.add_parser(\u0027upgrade\u0027,"},{"line_number":268,"context_line":"                                       help\u003d\"Upgrade the Northbound Database.\")"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a6eadb0_ea9e18b7","line":265,"range":{"start_line":250,"start_character":8,"end_line":265,"end_character":79},"in_reply_to":"1a6eadb0_3dfde13a","updated":"2016-12-14 07:46:58.000000000","message":"Agreed, will do","commit_id":"62cc29f310a68d56ed26e51ed7c8eb0fc9fad370"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"32264ec467e9e8a6c92631dabda8690446f00da1","unresolved":false,"context_lines":[{"line_number":255,"context_line":"    sub_parser.set_defaults(handle\u003dhandle)"},{"line_number":256,"context_line":""},{"line_number":257,"context_line":""},{"line_number":258,"context_line":"def _update_to_latest_nb(db_driver):"},{"line_number":259,"context_line":"    cur_version_num \u003d migration_common.get_current_db_version(db_driver)"},{"line_number":260,"context_line":"    all_versions \u003d migration_common.get_sorted_all_version_modules()"},{"line_number":261,"context_line":"    for version in all_versions:"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba5201f7_5b1d6b72","line":258,"range":{"start_line":258,"start_character":4,"end_line":258,"end_character":24},"updated":"2017-01-01 08:10:51.000000000","message":"If you change print -\u003e LOG.info, this method can sit in migration.common. Wouldn\u0027t that be better?","commit_id":"0a35bd8594af21327c90ba33cda8607f184ecec5"}],"dragonflow/db/migration.py":[{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"8b8c71c71313fec155a0110ce36929241a22e5e0","unresolved":false,"context_lines":[{"line_number":76,"context_line":"    for migration in sorted(all_migrations, key\u003dlambda m: m.proposed_at):"},{"line_number":77,"context_line":"        if migration.id in applied_migrations:"},{"line_number":78,"context_line":"            continue"},{"line_number":79,"context_line":"        migration.apply(nb_api)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"def mark_all_migrations_applied(nb_api):"}],"source_content_type":"text/x-python","patch_set":17,"id":"5f2577a7_2c6b541e","line":79,"range":{"start_line":79,"start_character":0,"end_line":79,"end_character":31},"updated":"2017-09-18 07:07:25.000000000","message":"What about \u0027apply\u0027 failure? How is that handled? How do you do rollback if needed?","commit_id":"29f05497cbd77b43de4eee56a1a859cba7f84590"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"e044ac17305a05ecc7d4ae7d7876e360742377ea","unresolved":false,"context_lines":[{"line_number":76,"context_line":"    for migration in sorted(all_migrations, key\u003dlambda m: m.proposed_at):"},{"line_number":77,"context_line":"        if migration.id in applied_migrations:"},{"line_number":78,"context_line":"            continue"},{"line_number":79,"context_line":"        migration.apply(nb_api)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"def mark_all_migrations_applied(nb_api):"}],"source_content_type":"text/x-python","patch_set":17,"id":"5f2577a7_ec530c38","line":79,"range":{"start_line":79,"start_character":0,"end_line":79,"end_character":31},"in_reply_to":"5f2577a7_2c6b541e","updated":"2017-09-18 07:18:23.000000000","message":"In the current approach, I cannot do much when a failure happens. Migration code halts and an exception is raised.\n\nIn this case someone has to come and interactively fix the issue. One of the issues here is that we lack any transaction-level facilities to interact with the database.\n\nWe should note that migration code can try handling the failures on their level, e.g. saving all changed objects and restoring them once done, so ideally, if a migration does that, and the core issue for its failure is resolved, we only need to kill the failed migration entry and rerun apply code.","commit_id":"29f05497cbd77b43de4eee56a1a859cba7f84590"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"8b8c71c71313fec155a0110ce36929241a22e5e0","unresolved":false,"context_lines":[{"line_number":108,"context_line":""},{"line_number":109,"context_line":"def _get_all_migration_entries():"},{"line_number":110,"context_line":"    for ext in stevedore.ExtensionManager("},{"line_number":111,"context_line":"        \u0027dragonflow.db.migrations\u0027,"},{"line_number":112,"context_line":"        invoke_on_load\u003dFalse,"},{"line_number":113,"context_line":"    ):"},{"line_number":114,"context_line":"        yield ext.plugin"}],"source_content_type":"text/x-python","patch_set":17,"id":"5f2577a7_ec1b0cc7","line":111,"range":{"start_line":111,"start_character":0,"end_line":111,"end_character":35},"updated":"2017-09-18 07:07:25.000000000","message":"Make constant","commit_id":"29f05497cbd77b43de4eee56a1a859cba7f84590"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"e044ac17305a05ecc7d4ae7d7876e360742377ea","unresolved":false,"context_lines":[{"line_number":108,"context_line":""},{"line_number":109,"context_line":"def _get_all_migration_entries():"},{"line_number":110,"context_line":"    for ext in stevedore.ExtensionManager("},{"line_number":111,"context_line":"        \u0027dragonflow.db.migrations\u0027,"},{"line_number":112,"context_line":"        invoke_on_load\u003dFalse,"},{"line_number":113,"context_line":"    ):"},{"line_number":114,"context_line":"        yield ext.plugin"}],"source_content_type":"text/x-python","patch_set":17,"id":"5f2577a7_ac3744ff","line":111,"range":{"start_line":111,"start_character":0,"end_line":111,"end_character":35},"in_reply_to":"5f2577a7_ec1b0cc7","updated":"2017-09-18 07:18:23.000000000","message":"Done","commit_id":"29f05497cbd77b43de4eee56a1a859cba7f84590"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"ff0f61a2c3edddbeb4f9501e51620aac377b2eb2","unresolved":false,"context_lines":[{"line_number":86,"context_line":"        self._internal_apply(nb_api)"},{"line_number":87,"context_line":"        nb_api.create(self)"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    def apply_norun(self, nb_api):"},{"line_number":90,"context_line":"        nb_api.create(self)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"def define_migration(affected_models, **kwargs):"}],"source_content_type":"text/x-python","patch_set":21,"id":"7f515b1d_02fcc6b2","line":90,"range":{"start_line":89,"start_character":0,"end_line":90,"end_character":27},"updated":"2017-10-01 12:37:41.000000000","message":"Is this function needed now?","commit_id":"159aaa6ed0a1e2415cc383680d532332dfded364"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"d3fd126e92259acd11e63345fde8409da74e8db9","unresolved":false,"context_lines":[{"line_number":86,"context_line":"        self._internal_apply(nb_api)"},{"line_number":87,"context_line":"        nb_api.create(self)"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    def apply_norun(self, nb_api):"},{"line_number":90,"context_line":"        nb_api.create(self)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"def define_migration(affected_models, **kwargs):"}],"source_content_type":"text/x-python","patch_set":21,"id":"3f4b6375_171b5081","line":90,"range":{"start_line":89,"start_character":0,"end_line":90,"end_character":27},"in_reply_to":"7f515b1d_02fcc6b2","updated":"2017-10-23 14:00:04.000000000","message":"Removed","commit_id":"159aaa6ed0a1e2415cc383680d532332dfded364"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"ff0f61a2c3edddbeb4f9501e51620aac377b2eb2","unresolved":false,"context_lines":[{"line_number":90,"context_line":"        nb_api.create(self)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"def define_migration(affected_models, **kwargs):"},{"line_number":94,"context_line":"    def decorator(func):"},{"line_number":95,"context_line":"        return SchemaMigration("},{"line_number":96,"context_line":"            upgrade_func\u003dfunc,"}],"source_content_type":"text/x-python","patch_set":21,"id":"7f515b1d_c2d8ee53","line":93,"range":{"start_line":93,"start_character":21,"end_line":93,"end_character":38},"updated":"2017-10-01 12:37:41.000000000","message":"Why was this added?","commit_id":"159aaa6ed0a1e2415cc383680d532332dfded364"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"d3fd126e92259acd11e63345fde8409da74e8db9","unresolved":false,"context_lines":[{"line_number":90,"context_line":"        nb_api.create(self)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"def define_migration(affected_models, **kwargs):"},{"line_number":94,"context_line":"    def decorator(func):"},{"line_number":95,"context_line":"        return SchemaMigration("},{"line_number":96,"context_line":"            upgrade_func\u003dfunc,"}],"source_content_type":"text/x-python","patch_set":21,"id":"3f4b6375_cb44fb1d","line":93,"range":{"start_line":93,"start_character":21,"end_line":93,"end_character":38},"in_reply_to":"7f515b1d_c2d8ee53","updated":"2017-10-23 14:00:04.000000000","message":"For documentation purposes.","commit_id":"159aaa6ed0a1e2415cc383680d532332dfded364"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"ff0f61a2c3edddbeb4f9501e51620aac377b2eb2","unresolved":false,"context_lines":[{"line_number":100,"context_line":""},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"def _get_applied_migrations(nb_api):"},{"line_number":103,"context_line":"    try:"},{"line_number":104,"context_line":"        return nb_api.get_all(SchemaMigration)"},{"line_number":105,"context_line":"    except exceptions.DBKeyNotFound:"},{"line_number":106,"context_line":"        return ()"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"def apply_new_migrations(nb_api):"}],"source_content_type":"text/x-python","patch_set":21,"id":"7f515b1d_421f5e07","line":106,"range":{"start_line":103,"start_character":0,"end_line":106,"end_character":17},"updated":"2017-10-01 12:37:41.000000000","message":"Nit: I think the API says that the try/catch isn\u0027t needed here.","commit_id":"159aaa6ed0a1e2415cc383680d532332dfded364"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"d3fd126e92259acd11e63345fde8409da74e8db9","unresolved":false,"context_lines":[{"line_number":100,"context_line":""},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"def _get_applied_migrations(nb_api):"},{"line_number":103,"context_line":"    try:"},{"line_number":104,"context_line":"        return nb_api.get_all(SchemaMigration)"},{"line_number":105,"context_line":"    except exceptions.DBKeyNotFound:"},{"line_number":106,"context_line":"        return ()"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"def apply_new_migrations(nb_api):"}],"source_content_type":"text/x-python","patch_set":21,"id":"3f4b6375_f798b41b","line":106,"range":{"start_line":103,"start_character":0,"end_line":106,"end_character":17},"in_reply_to":"7f515b1d_421f5e07","updated":"2017-10-23 14:00:04.000000000","message":"You\u0027re right.","commit_id":"159aaa6ed0a1e2415cc383680d532332dfded364"},{"author":{"_account_id":26131,"name":"Eyal Leshem","email":"eyal.leshem@toganetworks.com","username":"leyal"},"change_message_id":"d137f481942ce6ea24924ad12c5c80d65ec813a3","unresolved":false,"context_lines":[{"line_number":51,"context_line":"@contextlib.contextmanager"},{"line_number":52,"context_line":"def _transactional_nb_api(nb_api):"},{"line_number":53,"context_line":"    # FIXME (dimak): move out of testing"},{"line_number":54,"context_line":"    dummy_driver \u003d utils.load_driver("},{"line_number":55,"context_line":"            \u0027_dummy_nb_db_driver\u0027,"},{"line_number":56,"context_line":"            utils.DF_NB_DB_DRIVER_NAMESPACE)"},{"line_number":57,"context_line":"    dummy_driver.initialize(None, None, config\u003dNone)"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_affbf276","line":54,"updated":"2017-10-24 06:45:42.000000000","message":"I don\u0027t sure that dummy driver is a good name - \n(I mean the variable name - not the driver-name). \nwhen i read this function i think that the function is used for testing (even with the comment). \nMay in_mem_db , or migration_tmp_db could be better ..","commit_id":"ca97ef37e7fcef57d7ae92f0461a980d721c0ce5"},{"author":{"_account_id":26131,"name":"Eyal Leshem","email":"eyal.leshem@toganetworks.com","username":"leyal"},"change_message_id":"d137f481942ce6ea24924ad12c5c80d65ec813a3","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    return nb_api.get_all(SchemaMigration)"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"def apply_new_migrations(nb_api):"},{"line_number":102,"context_line":"    applied_migrations \u003d set(m.id for m in _get_applied_migrations(nb_api))"},{"line_number":103,"context_line":"    all_migrations \u003d find_all_migrations()"},{"line_number":104,"context_line":"    new_migrations \u003d ["}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_2a2a507e","line":101,"updated":"2017-10-24 06:45:42.000000000","message":"why we need to mark the applied migration ? \nCan\u0027t we choose the scripts according to the version to the version that we are upgrading. \n(For example : if we upgrade from pike to queens , we need to take all the script that grater then pike , equal or lower to queen)","commit_id":"ca97ef37e7fcef57d7ae92f0461a980d721c0ce5"},{"author":{"_account_id":26131,"name":"Eyal Leshem","email":"eyal.leshem@toganetworks.com","username":"leyal"},"change_message_id":"d137f481942ce6ea24924ad12c5c80d65ec813a3","unresolved":false,"context_lines":[{"line_number":134,"context_line":""},{"line_number":135,"context_line":"            loader \u003d importer.find_module(name)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"            if six.PY3:"},{"line_number":138,"context_line":"                yield loader.load_module(None)"},{"line_number":139,"context_line":"            else:"},{"line_number":140,"context_line":"                full_name \u003d \u0027{0}.{1}\u0027.format(entry.__name__, name)"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_2f64a249","line":137,"updated":"2017-10-24 06:45:42.000000000","message":"Maybe add comment here to explain the different between py3 and 2","commit_id":"ca97ef37e7fcef57d7ae92f0461a980d721c0ce5"},{"author":{"_account_id":6598,"name":"Berezovsky Irena","email":"irenab.dev@gmail.com","username":"irenab"},"change_message_id":"b566b9e9cb42c45bdc546b0fe74d31855a81fb04","unresolved":false,"context_lines":[{"line_number":50,"context_line":""},{"line_number":51,"context_line":"@contextlib.contextmanager"},{"line_number":52,"context_line":"def _transactional_nb_api(nb_api):"},{"line_number":53,"context_line":"    # FIXME (dimak): move out of testing"},{"line_number":54,"context_line":"    dummy_driver \u003d utils.load_driver("},{"line_number":55,"context_line":"            \u0027_dummy_nb_db_driver\u0027,"},{"line_number":56,"context_line":"            utils.DF_NB_DB_DRIVER_NAMESPACE)"}],"source_content_type":"text/x-python","patch_set":26,"id":"9f91af0f_73d22837","line":53,"range":{"start_line":53,"start_character":2,"end_line":53,"end_character":40},"updated":"2017-12-28 08:10:11.000000000","message":"is this comment still relevant?","commit_id":"176da96dc5e2dacc1aeb8da42c69126d245788bd"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"b73eb0eae61b80d99346ad0f90d15c5d2db16259","unresolved":false,"context_lines":[{"line_number":50,"context_line":""},{"line_number":51,"context_line":"@contextlib.contextmanager"},{"line_number":52,"context_line":"def _transactional_nb_api(nb_api):"},{"line_number":53,"context_line":"    # FIXME (dimak): move out of testing"},{"line_number":54,"context_line":"    dummy_driver \u003d utils.load_driver("},{"line_number":55,"context_line":"            \u0027_dummy_nb_db_driver\u0027,"},{"line_number":56,"context_line":"            utils.DF_NB_DB_DRIVER_NAMESPACE)"}],"source_content_type":"text/x-python","patch_set":26,"id":"9f91af0f_84492432","line":53,"range":{"start_line":53,"start_character":2,"end_line":53,"end_character":40},"in_reply_to":"9f91af0f_73d22837","updated":"2018-01-07 09:38:34.000000000","message":"Done","commit_id":"176da96dc5e2dacc1aeb8da42c69126d245788bd"},{"author":{"_account_id":26131,"name":"Eyal Leshem","email":"eyal.leshem@toganetworks.com","username":"leyal"},"change_message_id":"e475c7e730be0c59d122a69e1ccab5c7606af844","unresolved":false,"context_lines":[{"line_number":64,"context_line":""},{"line_number":65,"context_line":"@model_framework.register_model"},{"line_number":66,"context_line":"@model_framework.construct_nb_db_model"},{"line_number":67,"context_line":"class SchemaMigration(model_framework.ModelBase):"},{"line_number":68,"context_line":"    table_name \u003d \u0027schema_migration\u0027"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    description \u003d fields.StringField(required\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":30,"id":"3fa0c359_4f728faf","line":67,"updated":"2018-02-18 15:52:09.000000000","message":"maybe move that to separate file under dragonflow/db/models ?","commit_id":"1efa668e2bd4a647fc3ff232fc9ee41554697404"}],"dragonflow/db/migration/common.py":[{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"8026c6b74004e71eca348ca9194333e5733e79ba","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    for f in os.listdir(path):"},{"line_number":36,"context_line":"        mod_name, file_ext \u003d os.path.splitext(os.path.split(f)[-1])"},{"line_number":37,"context_line":"        mod_path \u003d os.path.join(path, f)"},{"line_number":38,"context_line":"        if (file_ext.lower() \u003d\u003d \u0027.py\u0027 and not mod_name \u003d\u003d current_mod_name"},{"line_number":39,"context_line":"                and not mod_name.startswith(\u0027_\u0027)):"},{"line_number":40,"context_line":"            mod \u003d imp.load_source(mod_name, mod_path)"},{"line_number":41,"context_line":"            mods.append(mod)"},{"line_number":42,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"1a6eadb0_2f0a0b27","line":39,"range":{"start_line":38,"start_character":0,"end_line":39,"end_character":50},"updated":"2016-12-13 13:44:19.000000000","message":"I think rather that blacklisting current file and __init__.py we should create a directory where all the files are upgrade python scripts.\n\nJust in case we add more python modules that are not upgrades.","commit_id":"62cc29f310a68d56ed26e51ed7c8eb0fc9fad370"},{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"fbd3b9e9894ee317314cc5ad5180e021db844672","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    for f in os.listdir(path):"},{"line_number":36,"context_line":"        mod_name, file_ext \u003d os.path.splitext(os.path.split(f)[-1])"},{"line_number":37,"context_line":"        mod_path \u003d os.path.join(path, f)"},{"line_number":38,"context_line":"        if (file_ext.lower() \u003d\u003d \u0027.py\u0027 and not mod_name \u003d\u003d current_mod_name"},{"line_number":39,"context_line":"                and not mod_name.startswith(\u0027_\u0027)):"},{"line_number":40,"context_line":"            mod \u003d imp.load_source(mod_name, mod_path)"},{"line_number":41,"context_line":"            mods.append(mod)"},{"line_number":42,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"1a6eadb0_caff9cff","line":39,"range":{"start_line":38,"start_character":0,"end_line":39,"end_character":50},"in_reply_to":"1a6eadb0_2f0a0b27","updated":"2016-12-14 07:46:58.000000000","message":"Agreed, will do","commit_id":"62cc29f310a68d56ed26e51ed7c8eb0fc9fad370"},{"author":{"_account_id":20287,"name":"hujie","email":"mike.hu@huawei.com","username":"hujie"},"change_message_id":"329cdbb0e30c45ab79a9e9a014e1bf6df2eb5ce2","unresolved":false,"context_lines":[{"line_number":71,"context_line":"    For some old data that created before unique_key, this method can"},{"line_number":72,"context_line":"    ensure there is no error when switching to new version."},{"line_number":73,"context_line":"    \"\"\""},{"line_number":74,"context_line":"    if not isinstance(nb_object, models.NbDbObjectWithUniqueKey):"},{"line_number":75,"context_line":"        return"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    if nb_object.get_unique_key():"},{"line_number":78,"context_line":"        return"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    unique_key \u003d db_driver.allocate_unique_key(nb_object.table_name)"},{"line_number":81,"context_line":"    nb_object.inner_obj.update({models.UNIQUE_KEY: unique_key})"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a6eadb0_5801cbad","line":78,"range":{"start_line":74,"start_character":4,"end_line":78,"end_character":14},"updated":"2016-12-13 14:20:34.000000000","message":"Could these two if be merged?","commit_id":"62cc29f310a68d56ed26e51ed7c8eb0fc9fad370"},{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"fbd3b9e9894ee317314cc5ad5180e021db844672","unresolved":false,"context_lines":[{"line_number":71,"context_line":"    For some old data that created before unique_key, this method can"},{"line_number":72,"context_line":"    ensure there is no error when switching to new version."},{"line_number":73,"context_line":"    \"\"\""},{"line_number":74,"context_line":"    if not isinstance(nb_object, models.NbDbObjectWithUniqueKey):"},{"line_number":75,"context_line":"        return"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    if nb_object.get_unique_key():"},{"line_number":78,"context_line":"        return"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    unique_key \u003d db_driver.allocate_unique_key(nb_object.table_name)"},{"line_number":81,"context_line":"    nb_object.inner_obj.update({models.UNIQUE_KEY: unique_key})"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a6eadb0_0a58b431","line":78,"range":{"start_line":74,"start_character":4,"end_line":78,"end_character":14},"in_reply_to":"1a6eadb0_5801cbad","updated":"2016-12-14 07:46:58.000000000","message":"They could be merged, but I want them to be separate, so that the reader will know that there are 2 cases that don\u0027t need the upgrade.","commit_id":"62cc29f310a68d56ed26e51ed7c8eb0fc9fad370"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"8371a47b1b521c079ca1eccac60a15be8dd2f1e0","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    path \u003d dragonflow.db.migration.scripts.__path__[0]"},{"line_number":33,"context_line":"    mods \u003d []"},{"line_number":34,"context_line":"    for f in os.listdir(path):"},{"line_number":35,"context_line":"        mod_name, file_ext \u003d os.path.splitext(os.path.split(f)[-1])"},{"line_number":36,"context_line":"        mod_path \u003d os.path.join(path, f)"},{"line_number":37,"context_line":"        if file_ext.lower() \u003d\u003d \u0027.py\u0027 and not mod_name.startswith(\u0027_\u0027):"},{"line_number":38,"context_line":"            mod \u003d imp.load_source(mod_name, mod_path)"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a6eadb0_4b7464fc","line":35,"range":{"start_line":35,"start_character":46,"end_line":35,"end_character":66},"updated":"2016-12-14 12:10:06.000000000","message":"Maybe you want os.path.basename?","commit_id":"ce800c0596ffe34c1236abd92618684c3b18159b"},{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"cfc1345fb634e7378b2cc97c197e6009e6743c2f","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    path \u003d dragonflow.db.migration.scripts.__path__[0]"},{"line_number":33,"context_line":"    mods \u003d []"},{"line_number":34,"context_line":"    for f in os.listdir(path):"},{"line_number":35,"context_line":"        mod_name, file_ext \u003d os.path.splitext(os.path.split(f)[-1])"},{"line_number":36,"context_line":"        mod_path \u003d os.path.join(path, f)"},{"line_number":37,"context_line":"        if file_ext.lower() \u003d\u003d \u0027.py\u0027 and not mod_name.startswith(\u0027_\u0027):"},{"line_number":38,"context_line":"            mod \u003d imp.load_source(mod_name, mod_path)"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a6eadb0_3573de16","line":35,"range":{"start_line":35,"start_character":46,"end_line":35,"end_character":66},"in_reply_to":"1a6eadb0_4b7464fc","updated":"2016-12-15 02:45:45.000000000","message":"thanks, will replace it.","commit_id":"ce800c0596ffe34c1236abd92618684c3b18159b"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"32264ec467e9e8a6c92631dabda8690446f00da1","unresolved":false,"context_lines":[{"line_number":42,"context_line":"    return mods"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"def get_current_db_version(db_driver):"},{"line_number":46,"context_line":"    cur_version_json \u003d db_driver.get_key(METADATA_TABLE_NAME,"},{"line_number":47,"context_line":"                                         MIGRATION_KEY)"},{"line_number":48,"context_line":"    if not cur_version_json:"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba5201f7_bb2577c3","line":45,"updated":"2017-01-01 08:10:51.000000000","message":"Maybe put this in nb_api?","commit_id":"0a35bd8594af21327c90ba33cda8607f184ecec5"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"32264ec467e9e8a6c92631dabda8690446f00da1","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    return cur_version[\u0027version\u0027]"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"def set_db_migration_metadata(db_driver, ver_mod):"},{"line_number":56,"context_line":"    date \u003d datetime.strptime(ver_mod.DATE, \u0027%Y-%m-%d %H:%M\u0027)"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    ver_obj \u003d {\u0027version\u0027: ver_mod.VERSION,"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba5201f7_db223bb9","line":55,"updated":"2017-01-01 08:10:51.000000000","message":"Same here.","commit_id":"0a35bd8594af21327c90ba33cda8607f184ecec5"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"25de5d0ae0519259cdbeab8a11d4033deb14f3ab","unresolved":false,"context_lines":[{"line_number":58,"context_line":"    ver_obj \u003d {\u0027version\u0027: ver_mod.VERSION,"},{"line_number":59,"context_line":"               \u0027description\u0027: ver_mod.DESCRIPTION,"},{"line_number":60,"context_line":"               \u0027os_version\u0027: ver_mod.OPENSTACK_VERSION,"},{"line_number":61,"context_line":"               \u0027date\u0027: str(date)}"},{"line_number":62,"context_line":"    db_driver.set_key(METADATA_TABLE_NAME, MIGRATION_KEY,"},{"line_number":63,"context_line":"                      jsonutils.dumps(ver_obj))"},{"line_number":64,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"1a6eadb0_97674d4c","line":61,"range":{"start_line":61,"start_character":23,"end_line":61,"end_character":32},"updated":"2016-12-15 09:22:53.000000000","message":"Why do we parse version.DATE and then format it to string again?","commit_id":"0a35bd8594af21327c90ba33cda8607f184ecec5"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"32264ec467e9e8a6c92631dabda8690446f00da1","unresolved":false,"context_lines":[{"line_number":58,"context_line":"    ver_obj \u003d {\u0027version\u0027: ver_mod.VERSION,"},{"line_number":59,"context_line":"               \u0027description\u0027: ver_mod.DESCRIPTION,"},{"line_number":60,"context_line":"               \u0027os_version\u0027: ver_mod.OPENSTACK_VERSION,"},{"line_number":61,"context_line":"               \u0027date\u0027: str(date)}"},{"line_number":62,"context_line":"    db_driver.set_key(METADATA_TABLE_NAME, MIGRATION_KEY,"},{"line_number":63,"context_line":"                      jsonutils.dumps(ver_obj))"},{"line_number":64,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"ba5201f7_fb2fff9e","line":61,"range":{"start_line":61,"start_character":23,"end_line":61,"end_character":32},"in_reply_to":"1a6eadb0_6d14a29f","updated":"2017-01-01 08:10:51.000000000","message":"We have both VERSION and DATE? Why not just date?","commit_id":"0a35bd8594af21327c90ba33cda8607f184ecec5"},{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"78c095303b7f6eb6ee6a1f6b645bcad5b177766a","unresolved":false,"context_lines":[{"line_number":58,"context_line":"    ver_obj \u003d {\u0027version\u0027: ver_mod.VERSION,"},{"line_number":59,"context_line":"               \u0027description\u0027: ver_mod.DESCRIPTION,"},{"line_number":60,"context_line":"               \u0027os_version\u0027: ver_mod.OPENSTACK_VERSION,"},{"line_number":61,"context_line":"               \u0027date\u0027: str(date)}"},{"line_number":62,"context_line":"    db_driver.set_key(METADATA_TABLE_NAME, MIGRATION_KEY,"},{"line_number":63,"context_line":"                      jsonutils.dumps(ver_obj))"},{"line_number":64,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"1a6eadb0_6d14a29f","line":61,"range":{"start_line":61,"start_character":23,"end_line":61,"end_character":32},"in_reply_to":"1a6eadb0_97674d4c","updated":"2016-12-15 09:58:01.000000000","message":"I hope that the date string can be localized this way.","commit_id":"0a35bd8594af21327c90ba33cda8607f184ecec5"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"e0621612d64e34cc42d1d5ea09adb0313572ef17","unresolved":false,"context_lines":[{"line_number":58,"context_line":""},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"def set_db_migration_metadata(db_driver, ver_mod):"},{"line_number":61,"context_line":"    ver_obj \u003d {\u0027description\u0027: ver_mod.DESCRIPTION,"},{"line_number":62,"context_line":"               \u0027os_version\u0027: ver_mod.OPENSTACK_VERSION,"},{"line_number":63,"context_line":"               \u0027date\u0027: ver_mod.DATE}"},{"line_number":64,"context_line":"    db_driver.set_key(METADATA_TABLE_NAME, MIGRATION_KEY,"},{"line_number":65,"context_line":"                      jsonutils.dumps(ver_obj))"},{"line_number":66,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"7f287b81_0709172b","line":63,"range":{"start_line":61,"start_character":0,"end_line":63,"end_character":36},"updated":"2017-08-23 20:35:12.000000000","message":"Maybe make it a model?","commit_id":"375bb520677c343aceab095540f69da08115bfff"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"93e207490975bb8943c64432d43f8fa52afcbd2e","unresolved":false,"context_lines":[{"line_number":30,"context_line":"    path \u003d dragonflow.db.migration.scripts.__path__[0]"},{"line_number":31,"context_line":"    mods \u003d []"},{"line_number":32,"context_line":"    for f in os.listdir(path):"},{"line_number":33,"context_line":"        mod_name, file_ext \u003d os.path.splitext(os.path.basename(f))"},{"line_number":34,"context_line":"        mod_path \u003d os.path.join(path, f)"},{"line_number":35,"context_line":"        if file_ext.lower() \u003d\u003d \u0027.py\u0027 and not mod_name.startswith(\u0027_\u0027):"},{"line_number":36,"context_line":"            mod \u003d imp.load_source(mod_name, mod_path)"},{"line_number":37,"context_line":"            mods.append(mod)"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    mods.sort(key\u003dlambda m: m.DATE)"},{"line_number":40,"context_line":"    return mods"}],"source_content_type":"text/x-python","patch_set":14,"id":"7f287b81_039a35c4","line":37,"range":{"start_line":33,"start_character":0,"end_line":37,"end_character":28},"updated":"2017-09-03 07:28:07.000000000","message":"Let\u0027s stevedorize the upgrade paths, so I am writing a stand-alone feature I can benefit from migration mechanism as well.","commit_id":"9755bbacf9c536309e9ee5714507b6bf666885c9"}],"dragonflow/db/migration/scripts/__init__.py":[{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"72ff8ff92e07c70178f1edd132d27eb0cfb21939","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"1a6eadb0_99bb37e5","line":1,"updated":"2016-12-14 11:07:43.000000000","message":"Do we need this file?\nUpgrade scripts only do absolute imports and dragonflow is in pythonpath, so I don\u0027t think we need upgrade scripts to be part of the package.","commit_id":"ce800c0596ffe34c1236abd92618684c3b18159b"},{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"5fe8677822db154b7de37627bbfbe90b5b566a69","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"1a6eadb0_c8a95ae1","line":1,"in_reply_to":"1a6eadb0_99bb37e5","updated":"2016-12-14 11:40:01.000000000","message":"If I don\u0027t add it, I will get an error to inform me that script can\u0027t be found at \n\nhttps://review.openstack.org/#/c/401210/4/dragonflow/db/migration/common.py@19","commit_id":"ce800c0596ffe34c1236abd92618684c3b18159b"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"8371a47b1b521c079ca1eccac60a15be8dd2f1e0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"1a6eadb0_eb27f00f","line":1,"in_reply_to":"1a6eadb0_c8a95ae1","updated":"2016-12-14 12:10:06.000000000","message":"Oh, right because then drangoflow.db.migration.scripts is not part of the package anymore...I don\u0027t like much but I can live with it. Just wanted to avoid filtering filename in the directory.","commit_id":"ce800c0596ffe34c1236abd92618684c3b18159b"}],"dragonflow/db/migration/scripts/lswitch_unique_key.py":[{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"32264ec467e9e8a6c92631dabda8690446f00da1","unresolved":false,"context_lines":[{"line_number":25,"context_line":"def upgrade(db_driver):"},{"line_number":26,"context_line":"    \"\"\"Check if the metadata has newer version. If not, upgrade it.\"\"\""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    cur_ver_num \u003d common.get_current_db_version(db_driver)"},{"line_number":29,"context_line":"    if cur_ver_num is not None and cur_ver_num \u003e\u003d VERSION:"},{"line_number":30,"context_line":"        return"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    # Do the migration"},{"line_number":33,"context_line":"    for lswitch_value in db_driver.get_all_entries("}],"source_content_type":"text/x-python","patch_set":7,"id":"ba5201f7_1b2da3a7","line":30,"range":{"start_line":28,"start_character":0,"end_line":30,"end_character":14},"updated":"2017-01-01 08:10:51.000000000","message":"This code will have to be repeated in every upgrade function. Is there a way to do it automatically/externally?","commit_id":"0a35bd8594af21327c90ba33cda8607f184ecec5"}],"dragonflow/tests/unit/test_db_migration.py":[{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"ff0f61a2c3edddbeb4f9501e51620aac377b2eb2","unresolved":false,"context_lines":[{"line_number":90,"context_line":""},{"line_number":91,"context_line":"    def test_find_all_migrations(self):"},{"line_number":92,"context_line":"        with mock.patch(\u0027stevedore.ExtensionManager\u0027, TestExtensionManager):"},{"line_number":93,"context_line":"            found_migrations \u003d tuple(migration.find_all_migrations())"},{"line_number":94,"context_line":"            self.assertItemsEqual("},{"line_number":95,"context_line":"                ("},{"line_number":96,"context_line":"                    migration1.migration.id,"}],"source_content_type":"text/x-python","patch_set":21,"id":"7f515b1d_42e4fe0c","line":93,"range":{"start_line":93,"start_character":31,"end_line":93,"end_character":69},"updated":"2017-10-01 12:37:41.000000000","message":"nit: Is wrapping in tuple really needed?","commit_id":"159aaa6ed0a1e2415cc383680d532332dfded364"}]}
