)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"cea5c0e12bc08fe86a36f7ff91d432240872b4f4","unresolved":false,"context_lines":[{"line_number":8,"context_line":"pci_device_pools from the database using PciDevice table"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"Change-Id: I9bec9f5f900a4f0f730b834aab4b71f21d68e686"},{"line_number":11,"context_line":"Implements: blueprint pci-generate-stats"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"7a740942_f225f55b","line":11,"updated":"2015-12-10 14:54:34.000000000","message":"This should be pci-stats-generate","commit_id":"e3fd0bb209446e9fd4a53c8c3055cd2731800e3a"},{"author":{"_account_id":6508,"name":"Dmitry Stepanenko","email":"dstepanenko@mirantis.com","username":"dstepanenko"},"change_message_id":"4624de0b748fef3b9ff3c94098ea0e465e4a59f5","unresolved":false,"context_lines":[{"line_number":8,"context_line":"pci_device_pools from the database using PciDevice table"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"Change-Id: I9bec9f5f900a4f0f730b834aab4b71f21d68e686"},{"line_number":11,"context_line":"Implements: blueprint pci-generate-stats"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"7a740942_6ec5993b","line":11,"in_reply_to":"7a740942_f225f55b","updated":"2015-12-10 17:02:20.000000000","message":"Done","commit_id":"e3fd0bb209446e9fd4a53c8c3055cd2731800e3a"}],"nova/db/api.py":[{"author":{"_account_id":17973,"name":"Ludovic Beliveau","email":"lbeliveau@gmail.com","username":"lbeliveau"},"change_message_id":"b68028a980cb3749d27657d850385cd8ae3a7fb7","unresolved":false,"context_lines":[{"line_number":1559,"context_line":""},{"line_number":1560,"context_line":""},{"line_number":1561,"context_line":"def pci_device_pools_get_all(context):"},{"line_number":1562,"context_line":"    \"\"\"Get all PCI devices for one host.\"\"\""},{"line_number":1563,"context_line":"    return IMPL.pci_device_pools_get_all(context)"},{"line_number":1564,"context_line":""},{"line_number":1565,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"3a57f1b5_7d199bd6","line":1562,"range":{"start_line":1562,"start_character":31,"end_line":1562,"end_character":34},"updated":"2016-02-11 17:21:12.000000000","message":"s/one/all","commit_id":"86d065de0a41319eb1c59241fff55fdbd62edc5c"},{"author":{"_account_id":6508,"name":"Dmitry Stepanenko","email":"dstepanenko@mirantis.com","username":"dstepanenko"},"change_message_id":"07f41ff261696fed25ced032fec27dc84d000dbe","unresolved":false,"context_lines":[{"line_number":1559,"context_line":""},{"line_number":1560,"context_line":""},{"line_number":1561,"context_line":"def pci_device_pools_get_all(context):"},{"line_number":1562,"context_line":"    \"\"\"Get all PCI devices for one host.\"\"\""},{"line_number":1563,"context_line":"    return IMPL.pci_device_pools_get_all(context)"},{"line_number":1564,"context_line":""},{"line_number":1565,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_cc356cf8","line":1562,"range":{"start_line":1562,"start_character":31,"end_line":1562,"end_character":34},"in_reply_to":"3a57f1b5_7d199bd6","updated":"2016-02-19 14:49:19.000000000","message":"Done","commit_id":"86d065de0a41319eb1c59241fff55fdbd62edc5c"}],"nova/db/sqlalchemy/api.py":[{"author":{"_account_id":19912,"name":"Xuanzhou Perry Dong","email":"oss_xzdong@163.com","username":"oss_xzdong"},"change_message_id":"b30d78014287deca02fad1e88e2d1f55258090a3","unresolved":false,"context_lines":[{"line_number":6493,"context_line":"    fields \u003d (\u0027compute_node_id\u0027, \u0027product_id\u0027, \u0027vendor_id\u0027,"},{"line_number":6494,"context_line":"                                        \u0027numa_node\u0027, \u0027count\u0027)"},{"line_number":6495,"context_line":""},{"line_number":6496,"context_line":"    \"\"\"query_result contains list of tuples, each of which contains values"},{"line_number":6497,"context_line":"    of fields compute_node_id, product_id, vendor_id, numa_node, count in"},{"line_number":6498,"context_line":"    that order. We need to parse it to the dict, where each key pair will"},{"line_number":6499,"context_line":"    be compute_node_id, list of pools for this node respectively"},{"line_number":6500,"context_line":"    \"\"\""},{"line_number":6501,"context_line":"    result \u003d {}"},{"line_number":6502,"context_line":"    for pool_properties in query_result:"},{"line_number":6503,"context_line":"        pool_dict \u003d {field: pool_properties[idx]"}],"source_content_type":"text/x-python","patch_set":17,"id":"7a5de9d1_5eafbd7c","line":6500,"range":{"start_line":6496,"start_character":2,"end_line":6500,"end_character":7},"updated":"2016-02-01 08:12:53.000000000","message":"Docstring doesn\u0027t seem to be appropriate here. Docstring is not stripped from the source after parsing. It should be used to document package/module/method usage, etc. Plain comment seems to be a better option here.","commit_id":"c5bddaaa83a031407a0912d0df856aabd7fe895e"},{"author":{"_account_id":6508,"name":"Dmitry Stepanenko","email":"dstepanenko@mirantis.com","username":"dstepanenko"},"change_message_id":"1e83e9f50464b5ce1996fac055dc77addabb1bd2","unresolved":false,"context_lines":[{"line_number":6493,"context_line":"    fields \u003d (\u0027compute_node_id\u0027, \u0027product_id\u0027, \u0027vendor_id\u0027,"},{"line_number":6494,"context_line":"                                        \u0027numa_node\u0027, \u0027count\u0027)"},{"line_number":6495,"context_line":""},{"line_number":6496,"context_line":"    \"\"\"query_result contains list of tuples, each of which contains values"},{"line_number":6497,"context_line":"    of fields compute_node_id, product_id, vendor_id, numa_node, count in"},{"line_number":6498,"context_line":"    that order. We need to parse it to the dict, where each key pair will"},{"line_number":6499,"context_line":"    be compute_node_id, list of pools for this node respectively"},{"line_number":6500,"context_line":"    \"\"\""},{"line_number":6501,"context_line":"    result \u003d {}"},{"line_number":6502,"context_line":"    for pool_properties in query_result:"},{"line_number":6503,"context_line":"        pool_dict \u003d {field: pool_properties[idx]"}],"source_content_type":"text/x-python","patch_set":17,"id":"7a5de9d1_32e6a2e8","line":6500,"range":{"start_line":6496,"start_character":2,"end_line":6500,"end_character":7},"in_reply_to":"7a5de9d1_5eafbd7c","updated":"2016-02-01 14:27:52.000000000","message":"Done","commit_id":"c5bddaaa83a031407a0912d0df856aabd7fe895e"},{"author":{"_account_id":19912,"name":"Xuanzhou Perry Dong","email":"oss_xzdong@163.com","username":"oss_xzdong"},"change_message_id":"b30d78014287deca02fad1e88e2d1f55258090a3","unresolved":false,"context_lines":[{"line_number":6503,"context_line":"        pool_dict \u003d {field: pool_properties[idx]"},{"line_number":6504,"context_line":"                        for idx, field in enumerate(fields)}"},{"line_number":6505,"context_line":"        compute_node_id \u003d pool_dict.pop(\u0027compute_node_id\u0027)"},{"line_number":6506,"context_line":"        if compute_node_id not in result:"},{"line_number":6507,"context_line":"            result[compute_node_id] \u003d [pool_dict]"},{"line_number":6508,"context_line":"        else:"},{"line_number":6509,"context_line":"            result[compute_node_id].append(pool_dict)"},{"line_number":6510,"context_line":""},{"line_number":6511,"context_line":"    return result"},{"line_number":6512,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"7a5de9d1_219ae0b9","line":6509,"range":{"start_line":6506,"start_character":0,"end_line":6509,"end_character":53},"updated":"2016-02-01 08:12:53.000000000","message":"How about: result.get(compute_node_id, []).append(pool_dict) ?","commit_id":"c5bddaaa83a031407a0912d0df856aabd7fe895e"},{"author":{"_account_id":6508,"name":"Dmitry Stepanenko","email":"dstepanenko@mirantis.com","username":"dstepanenko"},"change_message_id":"1e83e9f50464b5ce1996fac055dc77addabb1bd2","unresolved":false,"context_lines":[{"line_number":6503,"context_line":"        pool_dict \u003d {field: pool_properties[idx]"},{"line_number":6504,"context_line":"                        for idx, field in enumerate(fields)}"},{"line_number":6505,"context_line":"        compute_node_id \u003d pool_dict.pop(\u0027compute_node_id\u0027)"},{"line_number":6506,"context_line":"        if compute_node_id not in result:"},{"line_number":6507,"context_line":"            result[compute_node_id] \u003d [pool_dict]"},{"line_number":6508,"context_line":"        else:"},{"line_number":6509,"context_line":"            result[compute_node_id].append(pool_dict)"},{"line_number":6510,"context_line":""},{"line_number":6511,"context_line":"    return result"},{"line_number":6512,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"7a5de9d1_5200fe65","line":6509,"range":{"start_line":6506,"start_character":0,"end_line":6509,"end_character":53},"in_reply_to":"7a5de9d1_219ae0b9","updated":"2016-02-01 14:27:52.000000000","message":"It\u0027s not the same.\nIn case if result doesn\u0027t contain key with compute_note_id, your version of code will create empty list and add pool_dict to it as an element of list. No changes to original dict will be made.","commit_id":"c5bddaaa83a031407a0912d0df856aabd7fe895e"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"05ca6cbc29b4343647a6cae02a361b388404898f","unresolved":false,"context_lines":[{"line_number":6453,"context_line":"        if compute_node_id not in result:"},{"line_number":6454,"context_line":"            result[compute_node_id] \u003d [pool_dict]"},{"line_number":6455,"context_line":"        else:"},{"line_number":6456,"context_line":"            result[compute_node_id].append(pool_dict)"},{"line_number":6457,"context_line":""},{"line_number":6458,"context_line":"    return result"},{"line_number":6459,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"3a57f1b5_6fcfc87f","line":6456,"updated":"2016-02-11 06:37:57.000000000","message":"The return value from Query.all() is not a list of tuples. It\u0027s a list of ResultProxy objects actually:\n\nhttp://docs.sqlalchemy.org/en/latest/core/connections.html#sqlalchemy.engine.ResultProxy\n\nand thus you can access columns via index or field name dict-access.\n\nYou can use the field name dict access and use collections.defaultdict(list) to reduce the complexity of the above to just this:\n\n import collections\n ...\n\n results \u003d collections.defaultdict(list)\n for r in query_result:\n     pool_dict \u003d {f: r[f] for f in fields}\n     results[r.compute_node_id].append(pool_dict)\n return results","commit_id":"86d065de0a41319eb1c59241fff55fdbd62edc5c"},{"author":{"_account_id":6508,"name":"Dmitry Stepanenko","email":"dstepanenko@mirantis.com","username":"dstepanenko"},"change_message_id":"07f41ff261696fed25ced032fec27dc84d000dbe","unresolved":false,"context_lines":[{"line_number":6453,"context_line":"        if compute_node_id not in result:"},{"line_number":6454,"context_line":"            result[compute_node_id] \u003d [pool_dict]"},{"line_number":6455,"context_line":"        else:"},{"line_number":6456,"context_line":"            result[compute_node_id].append(pool_dict)"},{"line_number":6457,"context_line":""},{"line_number":6458,"context_line":"    return result"},{"line_number":6459,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_2c44d872","line":6456,"in_reply_to":"3a57f1b5_6fcfc87f","updated":"2016-02-19 14:49:19.000000000","message":"Done","commit_id":"86d065de0a41319eb1c59241fff55fdbd62edc5c"},{"author":{"_account_id":6508,"name":"Dmitry Stepanenko","email":"dstepanenko@mirantis.com","username":"dstepanenko"},"change_message_id":"4cdad2a35992c331a358b49b27bd05359bf9a2f3","unresolved":false,"context_lines":[{"line_number":6453,"context_line":"        if compute_node_id not in result:"},{"line_number":6454,"context_line":"            result[compute_node_id] \u003d [pool_dict]"},{"line_number":6455,"context_line":"        else:"},{"line_number":6456,"context_line":"            result[compute_node_id].append(pool_dict)"},{"line_number":6457,"context_line":""},{"line_number":6458,"context_line":"    return result"},{"line_number":6459,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_cc93a5f9","line":6456,"in_reply_to":"bae84128_2c44d872","updated":"2016-02-19 15:06:58.000000000","message":"Actually, I marked this comment as \"done\" by mistake. I tried to use your code and received \"tuple indexes should be \u0027int\u0027... \" error . I debuged this code a bit and found that model_query().all() returns list of \u003cclass \u0027sqlalchemy.util._collections.result\u0027\u003e. Does this match your understanding of this code, Jay? I tried to play with that and didn\u0027t succeeded so far.","commit_id":"86d065de0a41319eb1c59241fff55fdbd62edc5c"},{"author":{"_account_id":6508,"name":"Dmitry Stepanenko","email":"dstepanenko@mirantis.com","username":"dstepanenko"},"change_message_id":"ba0df1bc1ce5f4c3f5cc1c3b3ec349eba30f4a0a","unresolved":false,"context_lines":[{"line_number":6453,"context_line":"        if compute_node_id not in result:"},{"line_number":6454,"context_line":"            result[compute_node_id] \u003d [pool_dict]"},{"line_number":6455,"context_line":"        else:"},{"line_number":6456,"context_line":"            result[compute_node_id].append(pool_dict)"},{"line_number":6457,"context_line":""},{"line_number":6458,"context_line":"    return result"},{"line_number":6459,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_7cb5ddcb","line":6456,"in_reply_to":"bae84128_bc3f6c24","updated":"2016-02-19 17:44:35.000000000","message":"Now it\u0027s really done","commit_id":"86d065de0a41319eb1c59241fff55fdbd62edc5c"},{"author":{"_account_id":6508,"name":"Dmitry Stepanenko","email":"dstepanenko@mirantis.com","username":"dstepanenko"},"change_message_id":"617911cff1370b0dbb05056018fab6efb7d77f29","unresolved":false,"context_lines":[{"line_number":6453,"context_line":"        if compute_node_id not in result:"},{"line_number":6454,"context_line":"            result[compute_node_id] \u003d [pool_dict]"},{"line_number":6455,"context_line":"        else:"},{"line_number":6456,"context_line":"            result[compute_node_id].append(pool_dict)"},{"line_number":6457,"context_line":""},{"line_number":6458,"context_line":"    return result"},{"line_number":6459,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_bc3f6c24","line":6456,"in_reply_to":"bae84128_cc93a5f9","updated":"2016-02-19 15:46:43.000000000","message":"My bad, this code almost works. It should looks like \n\nfor r in query_result:\n    pool_dict \u003d {f: getattr(r, f)\n                 for f in fields}\n    ...\n\nso, instead of r[f] here we have getattr(r, f). The only issue is with the countable field called count. This code fails for it. Any ideas how to fix it?\n\nIt fails with error \"int() argument must be a string or a number, not \u0027builtin_function_or_method\u0027\". So, field \"count\" has such type instead of \u0027int\u0027.","commit_id":"86d065de0a41319eb1c59241fff55fdbd62edc5c"}],"nova/objects/pci_device_pool.py":[{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"7f0059726bdc7aa64f7172ef10823c740234b279","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    # Version 1.0: Initial version"},{"line_number":85,"context_line":"    #              PciDevicePool \u003c\u003d 1.0"},{"line_number":86,"context_line":"    # Version 1.1: PciDevicePool version 1.1"},{"line_number":87,"context_line":"    VERSION \u003d \u00271.1\u0027"},{"line_number":88,"context_line":"    fields \u003d {"},{"line_number":89,"context_line":"             \u0027objects\u0027: fields.ListOfObjectsField(\u0027PciDevicePool\u0027),"},{"line_number":90,"context_line":"             }"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a740942_c9dbb24e","line":87,"updated":"2015-12-09 14:42:06.000000000","message":"Because you are adding a remotable method, you need to update the version to \u00271.2\u0027 and add a comment saying you added get_all()","commit_id":"e3fd0bb209446e9fd4a53c8c3055cd2731800e3a"},{"author":{"_account_id":6508,"name":"Dmitry Stepanenko","email":"dstepanenko@mirantis.com","username":"dstepanenko"},"change_message_id":"4624de0b748fef3b9ff3c94098ea0e465e4a59f5","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    # Version 1.0: Initial version"},{"line_number":85,"context_line":"    #              PciDevicePool \u003c\u003d 1.0"},{"line_number":86,"context_line":"    # Version 1.1: PciDevicePool version 1.1"},{"line_number":87,"context_line":"    VERSION \u003d \u00271.1\u0027"},{"line_number":88,"context_line":"    fields \u003d {"},{"line_number":89,"context_line":"             \u0027objects\u0027: fields.ListOfObjectsField(\u0027PciDevicePool\u0027),"},{"line_number":90,"context_line":"             }"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a740942_29ec6bf2","line":87,"in_reply_to":"7a740942_c9dbb24e","updated":"2015-12-10 17:02:20.000000000","message":"Done","commit_id":"e3fd0bb209446e9fd4a53c8c3055cd2731800e3a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"05ca6cbc29b4343647a6cae02a361b388404898f","unresolved":false,"context_lines":[{"line_number":101,"context_line":"                                                    objects.PciDevicePool,"},{"line_number":102,"context_line":"                                                    pool_list)"},{"line_number":103,"context_line":"                for compute_node_id, pool_list in"},{"line_number":104,"context_line":"                        six.iteritems(pool_list_dict)}"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    @base.remotable_classmethod"},{"line_number":107,"context_line":"    def get_by_compute_node(cls, context, node_id):"}],"source_content_type":"text/x-python","patch_set":21,"id":"3a57f1b5_8fca446d","line":104,"updated":"2016-02-11 06:37:57.000000000","message":"No need to use six.iteritems()... just use pool_list_dict.items()","commit_id":"86d065de0a41319eb1c59241fff55fdbd62edc5c"},{"author":{"_account_id":6508,"name":"Dmitry Stepanenko","email":"dstepanenko@mirantis.com","username":"dstepanenko"},"change_message_id":"07f41ff261696fed25ced032fec27dc84d000dbe","unresolved":false,"context_lines":[{"line_number":101,"context_line":"                                                    objects.PciDevicePool,"},{"line_number":102,"context_line":"                                                    pool_list)"},{"line_number":103,"context_line":"                for compute_node_id, pool_list in"},{"line_number":104,"context_line":"                        six.iteritems(pool_list_dict)}"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    @base.remotable_classmethod"},{"line_number":107,"context_line":"    def get_by_compute_node(cls, context, node_id):"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_8cf9a450","line":104,"in_reply_to":"3a57f1b5_8fca446d","updated":"2016-02-19 14:49:19.000000000","message":"Done","commit_id":"86d065de0a41319eb1c59241fff55fdbd62edc5c"},{"author":{"_account_id":5511,"name":"Nikola Dipanov","email":"ndipanov@redhat.com","username":"ndipanov"},"change_message_id":"cd8dd7164db597453bb731566bea6941313b035c","unresolved":false,"context_lines":[{"line_number":96,"context_line":"    def get_all(cls, context):"},{"line_number":97,"context_line":"        with api.main_context_manager.reader.using(context):"},{"line_number":98,"context_line":"            query_result \u003d api.model_query(context, models.PciDevice, ("},{"line_number":99,"context_line":"                                            models.PciDevice.compute_node_id,"},{"line_number":100,"context_line":"                                            models.PciDevice.product_id,"},{"line_number":101,"context_line":"                                            models.PciDevice.vendor_id,"},{"line_number":102,"context_line":"                                            models.PciDevice.numa_node,"},{"line_number":103,"context_line":"                                            func.count(models.PciDevice.id)."},{"line_number":104,"context_line":"                                            label(\u0027count\u0027)"},{"line_number":105,"context_line":"                                        ), read_deleted\u003d\"no\").\\"}],"source_content_type":"text/x-python","patch_set":31,"id":"7af24918_6d7df3b0","line":102,"range":{"start_line":99,"start_character":44,"end_line":102,"end_character":71},"updated":"2016-03-02 12:00:06.000000000","message":"So by doing this we are completely dropping the tags. Tags are important for matching, and they are gathered from the PciDeviceSpec class (meaning they contain any freeform string that was found in the whitelist... I know, I know) See:\n\nhttps://github.com/openstack/nova/blob/040df06bfc45648c44066ecbefa215b6b76dad5a/nova/pci/stats.py#L95\n\nSo basically we\u0027d have to either codify the ones we care about and promote them to DB fields for your plan to use a GROUP_BY query to work (probably a good idea).\n\nWithout this we break neturon integration as it absolutely needs this to work based on (a totally random, I know, I know) \"physical_network\" key.\n\nhttps://github.com/openstack/nova/blob/040df06bfc45648c44066ecbefa215b6b76dad5a/nova/network/neutronv2/api.py#L1070","commit_id":"441b9971d3c44fd721c9c43508a5f5e42c616c7d"}]}
