)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"dbffc1e13c3a528386348e2786e36d7e90b1f5e3","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Eli Qiao \u003ctaget@linux.vnet.ibm.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2014-12-31 11:30:14 +0800"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Make sure sort_key_attr is InstrumentedAttribute when query"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When doing query.order_by, sort_key_attr is get from model class,"},{"line_number":10,"context_line":"we need to make sure sort_key_attr is really an InstrumentedAttribute"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"3a961159_00e8087b","line":7,"updated":"2015-01-05 08:56:13.000000000","message":"I\u0027m wondering if we should use QueryableAttribute instead here (http://docs.sqlalchemy.org/en/rel_0_8/orm/internals.html#sqlalchemy.orm.attributes.QueryableAttribute)","commit_id":"225c0e60437f1fa35947282f4a670e3505734f34"},{"author":{"_account_id":12175,"name":"Eli Qiao","email":"qiaoliyong@gmail.com","username":"Eli"},"change_message_id":"547ba9ffa4e1646995b410f22804dcadc95aa5e5","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Eli Qiao \u003ctaget@linux.vnet.ibm.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2014-12-31 11:30:14 +0800"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Make sure sort_key_attr is InstrumentedAttribute when query"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When doing query.order_by, sort_key_attr is get from model class,"},{"line_number":10,"context_line":"we need to make sure sort_key_attr is really an InstrumentedAttribute"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"3a961159_407690d9","line":7,"in_reply_to":"3a961159_00e8087b","updated":"2015-01-05 09:10:26.000000000","message":"hi Roman, \nmy debug show that the correct type is InstrumentedAttribute, but \nsqlalchemy.orm.attributes.QueryableAttribute is the base class of InstrumentedAttribute.\nseems much reasonable.\n\nthanks.","commit_id":"225c0e60437f1fa35947282f4a670e3505734f34"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"dbffc1e13c3a528386348e2786e36d7e90b1f5e3","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When doing query.order_by, sort_key_attr is get from model class,"},{"line_number":10,"context_line":"we need to make sure sort_key_attr is really an InstrumentedAttribute"},{"line_number":11,"context_line":"type instance before we do the query or it will casue errors."},{"line_number":12,"context_line":"This will prevent if there IS a function which name is same as sort_key."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Closes-Bug: 1405069"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"3a961159_c0ed2090","line":11,"updated":"2015-01-05 08:56:13.000000000","message":"type: cause","commit_id":"225c0e60437f1fa35947282f4a670e3505734f34"},{"author":{"_account_id":12175,"name":"Eli Qiao","email":"qiaoliyong@gmail.com","username":"Eli"},"change_message_id":"547ba9ffa4e1646995b410f22804dcadc95aa5e5","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When doing query.order_by, sort_key_attr is get from model class,"},{"line_number":10,"context_line":"we need to make sure sort_key_attr is really an InstrumentedAttribute"},{"line_number":11,"context_line":"type instance before we do the query or it will casue errors."},{"line_number":12,"context_line":"This will prevent if there IS a function which name is same as sort_key."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Closes-Bug: 1405069"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"3a961159_2070a4db","line":11,"in_reply_to":"3a961159_c0ed2090","updated":"2015-01-05 09:10:26.000000000","message":"Done","commit_id":"225c0e60437f1fa35947282f4a670e3505734f34"},{"author":{"_account_id":11189,"name":"yuntongjin","email":"yuntong.jin@intel.com","username":"yuntong"},"change_message_id":"bfb0b0e702cab230c6ce383429f294a79282bf10","unresolved":false,"context_lines":[{"line_number":9,"context_line":"When doing query.order_by, sort_key_attr is get from model class,"},{"line_number":10,"context_line":"we need to make sure sort_key_attr is really a QueryableAttribute"},{"line_number":11,"context_line":"type instance before we do the query or it will cause errors."},{"line_number":12,"context_line":"This will prevent if there IS a function which name is same as sort_key."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Closes-Bug: 1405069"},{"line_number":15,"context_line":"Change-Id: I8a3eb08ab3469ec08e05bfce754b664943d65c83"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"3a961159_2ea8798b","line":12,"updated":"2015-01-06 03:16:21.000000000","message":"IS/is\nwhich name/which the name","commit_id":"8b61920a7378ee3ce23fcf41ce8aef423fda3243"}],"oslo_db/sqlalchemy/utils.py":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"dbffc1e13c3a528386348e2786e36d7e90b1f5e3","unresolved":false,"context_lines":[{"line_number":151,"context_line":"            sort_key_attr \u003d getattr(model, current_sort_key)"},{"line_number":152,"context_line":"            # Make sure it is InstrumentedAttribute"},{"line_number":153,"context_line":"            if not isinstance(sort_key_attr, InstrumentedAttribute):"},{"line_number":154,"context_line":"                raise AttributeError"},{"line_number":155,"context_line":"        except AttributeError:"},{"line_number":156,"context_line":"            raise exception.InvalidSortKey()"},{"line_number":157,"context_line":"        query \u003d query.order_by(sort_dir_func(sort_key_attr))"}],"source_content_type":"text/x-python","patch_set":4,"id":"3a961159_40013038","line":154,"updated":"2015-01-05 08:56:13.000000000","message":"can we add a test for this?\n\n+ maybe TypeError is a better candidate for exception here","commit_id":"225c0e60437f1fa35947282f4a670e3505734f34"},{"author":{"_account_id":12175,"name":"Eli Qiao","email":"qiaoliyong@gmail.com","username":"Eli"},"change_message_id":"547ba9ffa4e1646995b410f22804dcadc95aa5e5","unresolved":false,"context_lines":[{"line_number":151,"context_line":"            sort_key_attr \u003d getattr(model, current_sort_key)"},{"line_number":152,"context_line":"            # Make sure it is InstrumentedAttribute"},{"line_number":153,"context_line":"            if not isinstance(sort_key_attr, InstrumentedAttribute):"},{"line_number":154,"context_line":"                raise AttributeError"},{"line_number":155,"context_line":"        except AttributeError:"},{"line_number":156,"context_line":"            raise exception.InvalidSortKey()"},{"line_number":157,"context_line":"        query \u003d query.order_by(sort_dir_func(sort_key_attr))"}],"source_content_type":"text/x-python","patch_set":4,"id":"3a961159_8005d815","line":154,"in_reply_to":"3a961159_40013038","updated":"2015-01-05 09:10:26.000000000","message":"hi Roman \ndo you expect this ?\n            if not isinstance(sort_key_attr, InstrumentedAttribute):\t153\n                raise TypeError\n     except AttributeError, TypeError:\n                raise exception.InvalidSortKey()","commit_id":"225c0e60437f1fa35947282f4a670e3505734f34"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"d456b106618263752fbfc39764f19ba24b0e7d7a","unresolved":false,"context_lines":[{"line_number":147,"context_line":"        except KeyError:"},{"line_number":148,"context_line":"            raise ValueError(_(\"Unknown sort direction, \""},{"line_number":149,"context_line":"                               \"must be \u0027desc\u0027 or \u0027asc\u0027\"))"},{"line_number":150,"context_line":"        try:"},{"line_number":151,"context_line":"            sort_key_attr \u003d getattr(model, current_sort_key)"},{"line_number":152,"context_line":"            # Make sure it is QueryableAttribute"},{"line_number":153,"context_line":"            if not isinstance(sort_key_attr, QueryableAttribute):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_b4a6640d","line":150,"updated":"2015-01-06 17:15:01.000000000","message":"there\u0027s a much more general way to do this:\n\n\tfrom sqlalchemy import inspect\n\n\ttry:\n\t    sort_key_attr \u003d inspect(model).all_orm_descriptors[current_sort_key]\n\texcept KeyError:\n\t    raise exception.InvalidSortKey(current_sort_key)\n\nsee http://docs.sqlalchemy.org/en/rel_0_9/orm/mapping_api.html?highlight\u003dall_orm_descriptors#sqlalchemy.orm.mapper.Mapper.all_orm_descriptors","commit_id":"05ddf630ed63abf9e36edb1a849135426615a09d"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"8f3187b9c45f2d5901fff69503a83982813db267","unresolved":false,"context_lines":[{"line_number":147,"context_line":"        except KeyError:"},{"line_number":148,"context_line":"            raise ValueError(_(\"Unknown sort direction, \""},{"line_number":149,"context_line":"                               \"must be \u0027desc\u0027 or \u0027asc\u0027\"))"},{"line_number":150,"context_line":"        try:"},{"line_number":151,"context_line":"            sort_key_attr \u003d getattr(model, current_sort_key)"},{"line_number":152,"context_line":"            # Make sure it is QueryableAttribute"},{"line_number":153,"context_line":"            if not isinstance(sort_key_attr, QueryableAttribute):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_8978512c","line":150,"in_reply_to":"3a961159_47ee62b6","updated":"2015-01-07 18:03:15.000000000","message":"those are weird tests.  I\u0027d just map a real class:\n\n\tclass MyModel(SomeBase):\n\t    x \u003d Column(Integer, primary_key\u003dTrue)\n\t    y \u003d Column(Integer)\n\t    # ...  etc.","commit_id":"05ddf630ed63abf9e36edb1a849135426615a09d"},{"author":{"_account_id":12175,"name":"Eli Qiao","email":"qiaoliyong@gmail.com","username":"Eli"},"change_message_id":"78bc90b47f9a16deee3fb43c4e5676dd51870284","unresolved":false,"context_lines":[{"line_number":147,"context_line":"        except KeyError:"},{"line_number":148,"context_line":"            raise ValueError(_(\"Unknown sort direction, \""},{"line_number":149,"context_line":"                               \"must be \u0027desc\u0027 or \u0027asc\u0027\"))"},{"line_number":150,"context_line":"        try:"},{"line_number":151,"context_line":"            sort_key_attr \u003d getattr(model, current_sort_key)"},{"line_number":152,"context_line":"            # Make sure it is QueryableAttribute"},{"line_number":153,"context_line":"            if not isinstance(sort_key_attr, QueryableAttribute):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_47ee62b6","line":150,"in_reply_to":"3a961159_b4a6640d","updated":"2015-01-07 08:38:53.000000000","message":"hi Michael\nthanks, it works for me, good to heard from you\nbut maybe difficute for me to fix the related test cases, maybe need more effort on changing test cases.\nI can not understand what marker and model should be \nthanks.Eli.","commit_id":"05ddf630ed63abf9e36edb1a849135426615a09d"}],"oslo_db/tests/old_import_api/sqlalchemy/test_utils.py":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"fc4129b15fc3d3d0968a709d8181a38c3b621639","unresolved":false,"context_lines":[{"line_number":103,"context_line":"        self.query \u003d self.mox.CreateMockAnything()"},{"line_number":104,"context_line":"        self.mox.StubOutWithMock(sqlalchemy, \u0027asc\u0027)"},{"line_number":105,"context_line":"        self.mox.StubOutWithMock(sqlalchemy, \u0027desc\u0027)"},{"line_number":106,"context_line":"        self.marker \u003d FakeTable"},{"line_number":107,"context_line":"        self.model \u003d FakeTable"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def test_paginate_query_no_pagination_no_sort_dirs(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a961159_e1cb971b","line":106,"updated":"2015-01-08 09:48:17.000000000","message":"I think, you really meant something like:\n\n  self.marker \u003d FakeTable(user_id\u003d\u0027user\u0027, project_id\u003d\u0027p\u0027, snapshot_id\u003d\u0027s\u0027)\n\nhere","commit_id":"78280cb3a8d2a3c9133fae5ea1d6ea8f45689a51"},{"author":{"_account_id":12175,"name":"Eli Qiao","email":"qiaoliyong@gmail.com","username":"Eli"},"change_message_id":"ec8a229a2813cadc3291e94794e7ce747031ab8d","unresolved":false,"context_lines":[{"line_number":103,"context_line":"        self.query \u003d self.mox.CreateMockAnything()"},{"line_number":104,"context_line":"        self.mox.StubOutWithMock(sqlalchemy, \u0027asc\u0027)"},{"line_number":105,"context_line":"        self.mox.StubOutWithMock(sqlalchemy, \u0027desc\u0027)"},{"line_number":106,"context_line":"        self.marker \u003d FakeTable"},{"line_number":107,"context_line":"        self.model \u003d FakeTable"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def test_paginate_query_no_pagination_no_sort_dirs(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a961159_9c4158a8","line":106,"in_reply_to":"3a961159_e1cb971b","updated":"2015-01-08 10:28:47.000000000","message":"Thanks , I will try it","commit_id":"78280cb3a8d2a3c9133fae5ea1d6ea8f45689a51"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"fc4129b15fc3d3d0968a709d8181a38c3b621639","unresolved":false,"context_lines":[{"line_number":138,"context_line":"                          self.model, 5, [\u0027user_id\u0027, \u0027non-existent key\u0027])"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"    def test_paginate_query_attribute_error_invalid_sortkey(self):"},{"line_number":141,"context_line":"        self.mox.ReplayAll()"},{"line_number":142,"context_line":"        self.assertRaises(exception.InvalidSortKey,"},{"line_number":143,"context_line":"                          utils.paginate_query, self.query,"},{"line_number":144,"context_line":"                          self.model, 5, [\u0027bad_user_id\u0027])"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a961159_a1dd0fdf","line":141,"updated":"2015-01-08 09:48:17.000000000","message":"nit: ReplayAll() must not be needed here, as we haven\u0027t mocked anything","commit_id":"78280cb3a8d2a3c9133fae5ea1d6ea8f45689a51"},{"author":{"_account_id":12175,"name":"Eli Qiao","email":"qiaoliyong@gmail.com","username":"Eli"},"change_message_id":"ec8a229a2813cadc3291e94794e7ce747031ab8d","unresolved":false,"context_lines":[{"line_number":138,"context_line":"                          self.model, 5, [\u0027user_id\u0027, \u0027non-existent key\u0027])"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"    def test_paginate_query_attribute_error_invalid_sortkey(self):"},{"line_number":141,"context_line":"        self.mox.ReplayAll()"},{"line_number":142,"context_line":"        self.assertRaises(exception.InvalidSortKey,"},{"line_number":143,"context_line":"                          utils.paginate_query, self.query,"},{"line_number":144,"context_line":"                          self.model, 5, [\u0027bad_user_id\u0027])"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a961159_7c466cc1","line":141,"in_reply_to":"3a961159_a1dd0fdf","updated":"2015-01-08 10:28:47.000000000","message":"Hi roman agree with you, but check Line 147 which is a bad example","commit_id":"78280cb3a8d2a3c9133fae5ea1d6ea8f45689a51"}],"oslo_db/tests/sqlalchemy/test_utils.py":[{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"8f3187b9c45f2d5901fff69503a83982813db267","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        self.mox \u003d mox_fixture.mox"},{"line_number":94,"context_line":"        self.query \u003d self.mox.CreateMockAnything()"},{"line_number":95,"context_line":"        self.mox.StubOutWithMock(sqlalchemy, \u0027asc\u0027)"},{"line_number":96,"context_line":"        self.mox.StubOutWithMock(sqlalchemy, \u0027desc\u0027)"},{"line_number":97,"context_line":"        self.marker \u003d FakeModel({"},{"line_number":98,"context_line":"            \u0027user_id\u0027: QueryableAttribute(object, \u0027user\u0027),"},{"line_number":99,"context_line":"            \u0027project_id\u0027: QueryableAttribute(object, \u0027p\u0027),"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_499ae962","line":96,"updated":"2015-01-07 18:03:15.000000000","message":"this would be better if we just made a real mapped class. then you get QueryableAttribute or whatever it will be for free.","commit_id":"05ddf630ed63abf9e36edb1a849135426615a09d"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"fc4129b15fc3d3d0968a709d8181a38c3b621639","unresolved":false,"context_lines":[{"line_number":102,"context_line":"        self.query \u003d self.mox.CreateMockAnything()"},{"line_number":103,"context_line":"        self.mox.StubOutWithMock(sqlalchemy, \u0027asc\u0027)"},{"line_number":104,"context_line":"        self.mox.StubOutWithMock(sqlalchemy, \u0027desc\u0027)"},{"line_number":105,"context_line":"        self.marker \u003d FakeTable"},{"line_number":106,"context_line":"        self.model \u003d FakeTable"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"    def test_paginate_query_no_pagination_no_sort_dirs(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a961159_01e6e3af","line":105,"updated":"2015-01-08 09:48:17.000000000","message":"marker ditto","commit_id":"78280cb3a8d2a3c9133fae5ea1d6ea8f45689a51"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"fc4129b15fc3d3d0968a709d8181a38c3b621639","unresolved":false,"context_lines":[{"line_number":137,"context_line":"                          self.model, 5, [\u0027user_id\u0027, \u0027non-existent key\u0027])"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    def test_paginate_query_attribute_error_invalid_sortkey(self):"},{"line_number":140,"context_line":"        self.mox.ReplayAll()"},{"line_number":141,"context_line":"        self.assertRaises(exception.InvalidSortKey,"},{"line_number":142,"context_line":"                          utils.paginate_query, self.query,"},{"line_number":143,"context_line":"                          self.model, 5, [\u0027bad_user_id\u0027])"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a961159_21e91f7f","line":140,"updated":"2015-01-08 09:48:17.000000000","message":"ReplayAll() ditto","commit_id":"78280cb3a8d2a3c9133fae5ea1d6ea8f45689a51"}]}
