)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"73f949a2bfe426db36932389365009514425a9db","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Add pagination support for sqlalchemy database"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Paginate db query result of sqlalchemy database."},{"line_number":10,"context_line":"The query methods support pagination include"},{"line_number":11,"context_line":"get_resources, get_meters, get_alarms."},{"line_number":12,"context_line":"It is part of bp/paginate-db-search."},{"line_number":13,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"AAAAP3%2F%2Fllw%3D","line":10,"updated":"2013-07-16 08:06:56.000000000","message":"s/The query methods support/The query methods that support/","commit_id":"b171d2a983b6d228f3cee07081fa91c94e155ec8"}],"ceilometer/storage/impl_sqlalchemy.py":[{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"8dec73c2fe51211076842cae6c6395429b73d548","unresolved":false,"context_lines":[{"line_number":227,"context_line":"    @staticmethod"},{"line_number":228,"context_line":"    def _get_marker(session, model, marker_pairs):"},{"line_number":229,"context_line":"        \"\"\"Return the mark object according to the key-value pairs."},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"        :param model: ORM model class that need be query."},{"line_number":232,"context_line":"        :param maker_pairs: Attribute-value pairs filter."},{"line_number":233,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAP3%2F%2F%2BMc%3D","line":230,"updated":"2013-07-08 10:27:11.000000000","message":"Missed :session: parameter","commit_id":"b171d2a983b6d228f3cee07081fa91c94e155ec8"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"56c42fe6a90d4e2d498db5be64fc172f5ae6ee01","unresolved":false,"context_lines":[{"line_number":243,"context_line":"                key_attr \u003d getattr(model, key)"},{"line_number":244,"context_line":"                query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":245,"context_line":"            ret \u003d query.one()"},{"line_number":246,"context_line":"        except AttributeError:"},{"line_number":247,"context_line":"            msg \u003d (_(\"No attribute %s found\") % key_attr)"},{"line_number":248,"context_line":"            LOG.warn(msg)"},{"line_number":249,"context_line":"            ret \u003d None"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAP3%2F%2FsfU%3D","line":246,"updated":"2013-07-12 21:09:22.000000000","message":"For the error handling here, if we don\u0027t find the requested object, shouldn\u0027t that result in an exception for the user? How will we compute the result set if we are asked to start with a specific object and can\u0027t find it?","commit_id":"b171d2a983b6d228f3cee07081fa91c94e155ec8"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"dcc83697036637412ef648b7e5054dd1c4ce2880","unresolved":false,"context_lines":[{"line_number":243,"context_line":"                key_attr \u003d getattr(model, key)"},{"line_number":244,"context_line":"                query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":245,"context_line":"            ret \u003d query.one()"},{"line_number":246,"context_line":"        except AttributeError:"},{"line_number":247,"context_line":"            msg \u003d (_(\"No attribute %s found\") % key_attr)"},{"line_number":248,"context_line":"            LOG.warn(msg)"},{"line_number":249,"context_line":"            ret \u003d None"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAP3%2F%2FhV4%3D","line":246,"in_reply_to":"AAAAP3%2F%2FliM%3D","updated":"2013-07-17 08:17:23.000000000","message":"i think both methods of *excluded* and *included* make sense.  For *included* method, i have a concern. when we got the first page and want to go to the second page, then we will see a same object as the previous page, the first one. This may not so convenient even some confusion to user.\n\nThanks\nFengqian","commit_id":"b171d2a983b6d228f3cee07081fa91c94e155ec8"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"73f949a2bfe426db36932389365009514425a9db","unresolved":false,"context_lines":[{"line_number":243,"context_line":"                key_attr \u003d getattr(model, key)"},{"line_number":244,"context_line":"                query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":245,"context_line":"            ret \u003d query.one()"},{"line_number":246,"context_line":"        except AttributeError:"},{"line_number":247,"context_line":"            msg \u003d (_(\"No attribute %s found\") % key_attr)"},{"line_number":248,"context_line":"            LOG.warn(msg)"},{"line_number":249,"context_line":"            ret \u003d None"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAP3%2F%2FliM%3D","line":246,"in_reply_to":"AAAAP3%2F%2FsfU%3D","updated":"2013-07-16 08:06:56.000000000","message":"So maybe I\u0027m being naive here, but I was thinking the usual usage pattern for the pagination marker would be to specify the last item of the previously returned resultset as the start marker for the next paginated query, but with the understanding that this element will be excluded from the next resultset returned.\n\nNow that marker item could have been deleted between the successive queries, but all is not necessarily lost at that point as that deleted element is not required in the next result set.\n\nSo what if we were just to find the first item greater than the marker (in whatever sort order) and simply use that as an *included* start element? (as opposed to an *excluded* start element).\n\nThat approach would protect the logic against deletes interleaved between paginated queries.","commit_id":"b171d2a983b6d228f3cee07081fa91c94e155ec8"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"ea94eead87bf10176f1b45c2d04c42c53b76e21f","unresolved":false,"context_lines":[{"line_number":272,"context_line":"            key_attr \u003d getattr(model, key)"},{"line_number":273,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":274,"context_line":"        return query.one()"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"    @staticmethod"},{"line_number":277,"context_line":"    def get_users(source\u003dNone):"},{"line_number":278,"context_line":"        \"\"\"Return an iterable of user id strings."}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAQn%2F%2F2LA%3D","line":275,"updated":"2013-07-22 07:59:13.000000000","message":"Just wondering when the marker returns no result or multiple results, whether it\u0027s ok to have sqlalchemy behave different with mongodb?","commit_id":"0721d3e3dd25686a88358f4a24e2f553fc89eb89"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"073a81e3d842e5a6fadefdce29e2d5798e4dbc76","unresolved":false,"context_lines":[{"line_number":145,"context_line":"    sort_keys_extra \u003d {\u0027alarm\u0027: [\u0027name\u0027, \u0027user_id\u0027, \u0027project_id\u0027],"},{"line_number":146,"context_line":"                       \u0027meter\u0027: [\u0027user_id\u0027, \u0027project_id\u0027],"},{"line_number":147,"context_line":"                       \u0027resource\u0027: [\u0027resource_id\u0027, \u0027user_id\u0027, \u0027project_id\u0027],"},{"line_number":148,"context_line":"                       }"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"    def __init__(self, conf):"},{"line_number":151,"context_line":"        url \u003d conf.database.connection"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAQn%2F%2Fn14%3D","line":148,"updated":"2013-07-26 10:03:35.000000000","message":"I sure this code can be moved to the base.py because I have see the same in the mongodb implementation","commit_id":"b325f078c2ab5477295d5db7e1bccddb2e263b23"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"073a81e3d842e5a6fadefdce29e2d5798e4dbc76","unresolved":false,"context_lines":[{"line_number":252,"context_line":"        query.delete(synchronize_session\u003d\u0027fetch\u0027)"},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"    @staticmethod"},{"line_number":255,"context_line":"    def _handle_sort_key(model_name, sort_key):"},{"line_number":256,"context_line":"        \"\"\"Generate sort keys according to the passed in sort key from user."},{"line_number":257,"context_line":""},{"line_number":258,"context_line":"        :param model_name: Database model name be query.(alarm, meter, etc.)"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAQn%2F%2Fn2Y%3D","line":255,"updated":"2013-07-26 10:03:35.000000000","message":"Same here","commit_id":"b325f078c2ab5477295d5db7e1bccddb2e263b23"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"073a81e3d842e5a6fadefdce29e2d5798e4dbc76","unresolved":false,"context_lines":[{"line_number":282,"context_line":"            return"},{"line_number":283,"context_line":"        if session is None:"},{"line_number":284,"context_line":"            session \u003d sqlalchemy_session.get_session()"},{"line_number":285,"context_line":"        query \u003d session.query(model)"},{"line_number":286,"context_line":""},{"line_number":287,"context_line":"        for key, value in marker_pairs.iteritems():"},{"line_number":288,"context_line":"            key_attr \u003d getattr(model, key)"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAQn%2F%2Fn2k%3D","line":285,"updated":"2013-07-26 10:03:35.000000000","message":"limit\u003d2 can be added","commit_id":"b325f078c2ab5477295d5db7e1bccddb2e263b23"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"18b64ab3c09f3b259b71d9667aa21a1bb0b192af","unresolved":false,"context_lines":[{"line_number":300,"context_line":"                      start_timestamp\u003dNone, start_timestamp_op\u003dNone,"},{"line_number":301,"context_line":"                      end_timestamp\u003dNone, end_timestamp_op\u003dNone,"},{"line_number":302,"context_line":"                      metaquery\u003d{}, resource\u003dNone, limit\u003dNone,"},{"line_number":303,"context_line":"                      marker_pairs\u003dNone, sort_key\u003dNone, sort_dir\u003dNone):"},{"line_number":304,"context_line":"        \"\"\"Return an iterable of api_models.Resource instances"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"        :param user: Optional ID for user that owns the resource."}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAQn%2F%2B87c%3D","line":303,"updated":"2013-08-09 12:57:13.000000000","message":"set sort_dir\u003d\u0027desc\u0027 instead of setting it in openstack.common code.\n\nsame for below cases","commit_id":"b5b2bba5a02907ef5690a0f1c7b87c19d7735214"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"795ff82d896f2f1295ca0586c9ad434aa9ebf7d6","unresolved":false,"context_lines":[{"line_number":274,"context_line":""},{"line_number":275,"context_line":"    # copy from glance/db/sqlalchemy/api.py"},{"line_number":276,"context_line":"    @classmethod"},{"line_number":277,"context_line":"    def paginate_query(cls, query, model, limit, sort_keys, marker\u003dNone,"},{"line_number":278,"context_line":"                       sort_dir\u003dNone, sort_dirs\u003dNone):"},{"line_number":279,"context_line":"        \"\"\"Returns a query with sorting / pagination criteria added."},{"line_number":280,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAQn%2F%2B8qk%3D","line":277,"updated":"2013-08-09 14:35:57.000000000","message":"why don\u0027t you use paginate_query() from common oslo code? It looks similar","commit_id":"0fa65e11fcf9a673e69eac402fae2359bbe4204c"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"3250110a58ebee86deff1835133661eaa7ebcec6","unresolved":false,"context_lines":[{"line_number":274,"context_line":""},{"line_number":275,"context_line":"    # copy from glance/db/sqlalchemy/api.py"},{"line_number":276,"context_line":"    @classmethod"},{"line_number":277,"context_line":"    def paginate_query(cls, query, model, limit, sort_keys, marker\u003dNone,"},{"line_number":278,"context_line":"                       sort_dir\u003dNone, sort_dirs\u003dNone):"},{"line_number":279,"context_line":"        \"\"\"Returns a query with sorting / pagination criteria added."},{"line_number":280,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAQn%2F%2B8lY%3D","line":277,"in_reply_to":"AAAAQn%2F%2B8qk%3D","updated":"2013-08-09 14:51:15.000000000","message":"actually, it is almost the same as the paginate_query() from common oslo code except the default sort direction is changed to \u0027desc\u0027. I did this change and wanted to keep in line with the default sort direction of mongodb pagination query method, which has been merged already. \n\nThanks\n\n\nFengqian","commit_id":"0fa65e11fcf9a673e69eac402fae2359bbe4204c"},{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"79dd2fd324750cf49ff029bc225fa648cdb21e63","unresolved":false,"context_lines":[{"line_number":254,"context_line":"        :param model: ORM model class that need be query."},{"line_number":255,"context_line":"        :param maker_pairs: Attribute-value pairs filter."},{"line_number":256,"context_line":"        \"\"\""},{"line_number":257,"context_line":"        if not (model and marker_pairs):"},{"line_number":258,"context_line":"            return"},{"line_number":259,"context_line":"        if session is None:"},{"line_number":260,"context_line":"            session \u003d sqlalchemy_session.get_session()"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQn%2F%2B74o%3D","line":257,"updated":"2013-08-09 17:54:53.000000000","message":"Is the test for this covered in the base tests?","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"79dd2fd324750cf49ff029bc225fa648cdb21e63","unresolved":false,"context_lines":[{"line_number":256,"context_line":"        \"\"\""},{"line_number":257,"context_line":"        if not (model and marker_pairs):"},{"line_number":258,"context_line":"            return"},{"line_number":259,"context_line":"        if session is None:"},{"line_number":260,"context_line":"            session \u003d sqlalchemy_session.get_session()"},{"line_number":261,"context_line":"        query \u003d session.query(model)"},{"line_number":262,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQn%2F%2B75o%3D","line":259,"updated":"2013-08-09 17:54:53.000000000","message":"There isn\u0027t any place that session is not passed in. Do we need this?","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"d9782a77323042214854e141a99d7b01967d29a2","unresolved":false,"context_lines":[{"line_number":256,"context_line":"        \"\"\""},{"line_number":257,"context_line":"        if not (model and marker_pairs):"},{"line_number":258,"context_line":"            return"},{"line_number":259,"context_line":"        if session is None:"},{"line_number":260,"context_line":"            session \u003d sqlalchemy_session.get_session()"},{"line_number":261,"context_line":"        query \u003d session.query(model)"},{"line_number":262,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQ3%2F%2F%2Fsg%3D","line":259,"in_reply_to":"AAAAQn%2F%2B75o%3D","updated":"2013-08-11 09:44:46.000000000","message":"Will remove in next patch set","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"79dd2fd324750cf49ff029bc225fa648cdb21e63","unresolved":false,"context_lines":[{"line_number":265,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":266,"context_line":"        query \u003d query.limit(2)"},{"line_number":267,"context_line":"        if query.count() \u003e 1:"},{"line_number":268,"context_line":"            raise base.MultipleResultsFound"},{"line_number":269,"context_line":"        elif query.count() \u003c\u003d 0:"},{"line_number":270,"context_line":"            raise base.NoResultFound"},{"line_number":271,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQn%2F%2B75g%3D","line":268,"updated":"2013-08-09 17:54:53.000000000","message":"Should we raise, or clean up the mess and continue?\n\nIs the test for this covered in the base tests?","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"e893dd2051ac4b345f61314d1509e8b2a781f82d","unresolved":false,"context_lines":[{"line_number":265,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":266,"context_line":"        query \u003d query.limit(2)"},{"line_number":267,"context_line":"        if query.count() \u003e 1:"},{"line_number":268,"context_line":"            raise base.MultipleResultsFound"},{"line_number":269,"context_line":"        elif query.count() \u003c\u003d 0:"},{"line_number":270,"context_line":"            raise base.NoResultFound"},{"line_number":271,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQ3%2F%2F83o%3D","line":268,"in_reply_to":"AAAAQ3%2F%2F%2FsE%3D","updated":"2013-08-12 15:52:59.000000000","message":"But how will they ever get past this? Will the database just grow will duplicate markers?","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"db4f9c9d8186eef7b438d32154d129484e2d4751","unresolved":false,"context_lines":[{"line_number":265,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":266,"context_line":"        query \u003d query.limit(2)"},{"line_number":267,"context_line":"        if query.count() \u003e 1:"},{"line_number":268,"context_line":"            raise base.MultipleResultsFound"},{"line_number":269,"context_line":"        elif query.count() \u003c\u003d 0:"},{"line_number":270,"context_line":"            raise base.NoResultFound"},{"line_number":271,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQ3%2F%2F4us%3D","line":268,"in_reply_to":"AAAAQ3%2F%2F41I%3D","updated":"2013-08-13 13:55:48.000000000","message":"yes, i agree. If the marker pairs that user passed in could not identify unique object,  for example, got more than one object, we should raise the exception and user will realize that they need to provide a more specific marker.\n\nBut i did not quit clear about your words, \"For these situations I think it\u0027s better to clean up the offending database issues and carry on.\", could you explain more clearly?\n\n\nFengqian","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"6dbc11e71e06e9e8481bafb198cfc98163f4dfb7","unresolved":false,"context_lines":[{"line_number":265,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":266,"context_line":"        query \u003d query.limit(2)"},{"line_number":267,"context_line":"        if query.count() \u003e 1:"},{"line_number":268,"context_line":"            raise base.MultipleResultsFound"},{"line_number":269,"context_line":"        elif query.count() \u003c\u003d 0:"},{"line_number":270,"context_line":"            raise base.NoResultFound"},{"line_number":271,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQ3%2F%2F4i0%3D","line":268,"in_reply_to":"AAAAQ3%2F%2F4lo%3D","updated":"2013-08-13 14:35:04.000000000","message":"sorry for the unclear expression:).\n\nMaybe i think too much about this. I mean if the parameters passed in could not determine the last record, for example, users passed in (name \u003d test) and want to identify a unique alarm object in database while we have more than one alarm objects with name \u003d test.\n\n\nBut if users know enough about the database, they will not act like this, they will pass in a specific marker.\n\n\nThanks\n\nFengqian","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"b355338af942ad4ef62fff5250f6046e0f99362f","unresolved":false,"context_lines":[{"line_number":265,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":266,"context_line":"        query \u003d query.limit(2)"},{"line_number":267,"context_line":"        if query.count() \u003e 1:"},{"line_number":268,"context_line":"            raise base.MultipleResultsFound"},{"line_number":269,"context_line":"        elif query.count() \u003c\u003d 0:"},{"line_number":270,"context_line":"            raise base.NoResultFound"},{"line_number":271,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQ3%2F%2F4lo%3D","line":268,"in_reply_to":"AAAAQ3%2F%2F4oE%3D","updated":"2013-08-13 14:24:55.000000000","message":"(sorry, I don\u0027t really understand your last sentence)\n\nDo we even need to use the database for this? Can\u0027t we just pass in parameters in the REST request (like a datetime + milliseconds) to determine where the last record was? \n\nStoring client state in the server is always a bad idea and true REST implies that state is stored in the client.","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"ef8c6127dd5e1ccfa3e2d010b9a41e2b5bda713c","unresolved":false,"context_lines":[{"line_number":265,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":266,"context_line":"        query \u003d query.limit(2)"},{"line_number":267,"context_line":"        if query.count() \u003e 1:"},{"line_number":268,"context_line":"            raise base.MultipleResultsFound"},{"line_number":269,"context_line":"        elif query.count() \u003c\u003d 0:"},{"line_number":270,"context_line":"            raise base.NoResultFound"},{"line_number":271,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQ3%2F%2F4oE%3D","line":268,"in_reply_to":"AAAAQ3%2F%2F4rM%3D","updated":"2013-08-13 14:16:54.000000000","message":"actually, that is long story here:). we are discuss about this all the time. So, here is my opinion now, how about we just use only one marker pairs, which means we request users only passed in one single marker, and use it to get the marker object and do the following actions for pagination. \n\n\nEven that marker could not identify a unique marker object, we still going on and return, maybe the results is not the expected. Does this make sense?\n\n\nTHanks\n\n\nFengqian","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"74de757640dc81de1a46c2f3ef4de8b9822c3199","unresolved":false,"context_lines":[{"line_number":265,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":266,"context_line":"        query \u003d query.limit(2)"},{"line_number":267,"context_line":"        if query.count() \u003e 1:"},{"line_number":268,"context_line":"            raise base.MultipleResultsFound"},{"line_number":269,"context_line":"        elif query.count() \u003c\u003d 0:"},{"line_number":270,"context_line":"            raise base.NoResultFound"},{"line_number":271,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQ3%2F%2F4rM%3D","line":268,"in_reply_to":"AAAAQ3%2F%2F4us%3D","updated":"2013-08-13 14:06:13.000000000","message":":)\n\nHow would the user give a more specific marker? I assume the ceilometer client would be taking care of the paging and it\u0027s already given the best guess.\n\nIf we see \u003e 1 marker, we should use the first and delete the rest.  The user may get back duplicates or miss something, but it\u0027s better than an error he can\u0027t recover from or a growing database (because the user would need to re-issue the whole query in order to get a new marker set).\n\nThe use-case for this problem is two requests coming in at the same time resulting in two new marker sets being produced. The proper solution would be to constrain the db, but barring that, we have to make assumptions on how to clean up any mess.","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"c6bba62fd11602bf7e52e48e7e078adf53b046c0","unresolved":false,"context_lines":[{"line_number":265,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":266,"context_line":"        query \u003d query.limit(2)"},{"line_number":267,"context_line":"        if query.count() \u003e 1:"},{"line_number":268,"context_line":"            raise base.MultipleResultsFound"},{"line_number":269,"context_line":"        elif query.count() \u003c\u003d 0:"},{"line_number":270,"context_line":"            raise base.NoResultFound"},{"line_number":271,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQ3%2F%2F41I%3D","line":268,"in_reply_to":"AAAAQ3%2F%2F6sU%3D","updated":"2013-08-13 13:34:09.000000000","message":"Well, that\u0027s my point. If, for whatever reason, we get a duplicate marker, there is no way for it to get fixed without admin intervention. For these situations I think it\u0027s better to clean up the offending database issues and carry on. \n\nOr, put constraints in the db model so this situation can\u0027t occur in the first place.","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"acfb23342f33f9b22db5ec810f76168f94556d10","unresolved":false,"context_lines":[{"line_number":265,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":266,"context_line":"        query \u003d query.limit(2)"},{"line_number":267,"context_line":"        if query.count() \u003e 1:"},{"line_number":268,"context_line":"            raise base.MultipleResultsFound"},{"line_number":269,"context_line":"        elif query.count() \u003c\u003d 0:"},{"line_number":270,"context_line":"            raise base.NoResultFound"},{"line_number":271,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQ3%2F%2F6sU%3D","line":268,"in_reply_to":"AAAAQ3%2F%2F83o%3D","updated":"2013-08-13 00:58:08.000000000","message":"@Sandy Walsh\t\n\n\nNo, i was assume that users did not know too much about the database, so the marker they passed in may not unique to identity one object. \n\n\nThanks\n\n\nFengqian","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"d9782a77323042214854e141a99d7b01967d29a2","unresolved":false,"context_lines":[{"line_number":265,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":266,"context_line":"        query \u003d query.limit(2)"},{"line_number":267,"context_line":"        if query.count() \u003e 1:"},{"line_number":268,"context_line":"            raise base.MultipleResultsFound"},{"line_number":269,"context_line":"        elif query.count() \u003c\u003d 0:"},{"line_number":270,"context_line":"            raise base.NoResultFound"},{"line_number":271,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQ3%2F%2F%2FsE%3D","line":268,"in_reply_to":"AAAAQn%2F%2B75g%3D","updated":"2013-08-11 09:44:46.000000000","message":"@Sandy Walsh:\n\nI think we\u0027d better to raise the exception here. If we continue here, users are very likely to get the query results that dispatch with their expectation, which will confuse them.","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"79dd2fd324750cf49ff029bc225fa648cdb21e63","unresolved":false,"context_lines":[{"line_number":267,"context_line":"        if query.count() \u003e 1:"},{"line_number":268,"context_line":"            raise base.MultipleResultsFound"},{"line_number":269,"context_line":"        elif query.count() \u003c\u003d 0:"},{"line_number":270,"context_line":"            raise base.NoResultFound"},{"line_number":271,"context_line":"        else:"},{"line_number":272,"context_line":"            return query.one()"},{"line_number":273,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQn%2F%2B74E%3D","line":270,"updated":"2013-08-09 17:54:53.000000000","message":"Is the test for this covered in the base tests?","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"79dd2fd324750cf49ff029bc225fa648cdb21e63","unresolved":false,"context_lines":[{"line_number":345,"context_line":"        if metaquery:"},{"line_number":346,"context_line":"            raise NotImplementedError(\u0027metaquery not implemented\u0027)"},{"line_number":347,"context_line":""},{"line_number":348,"context_line":"        marker \u003d Connection._get_marker(session, Meter, marker_pairs)"},{"line_number":349,"context_line":"        sort_keys \u003d base._handle_sort_key(\u0027resource\u0027, sort_key)"},{"line_number":350,"context_line":""},{"line_number":351,"context_line":"        query \u003d sqlalchemy_utils.paginate_query(query, Meter, limit\u003dlimit,"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQn%2F%2B740%3D","line":348,"updated":"2013-08-09 17:54:53.000000000","message":"What if marker \u003d None?","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"d9782a77323042214854e141a99d7b01967d29a2","unresolved":false,"context_lines":[{"line_number":345,"context_line":"        if metaquery:"},{"line_number":346,"context_line":"            raise NotImplementedError(\u0027metaquery not implemented\u0027)"},{"line_number":347,"context_line":""},{"line_number":348,"context_line":"        marker \u003d Connection._get_marker(session, Meter, marker_pairs)"},{"line_number":349,"context_line":"        sort_keys \u003d base._handle_sort_key(\u0027resource\u0027, sort_key)"},{"line_number":350,"context_line":""},{"line_number":351,"context_line":"        query \u003d sqlalchemy_utils.paginate_query(query, Meter, limit\u003dlimit,"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAQ3%2F%2F%2Fsk%3D","line":348,"in_reply_to":"AAAAQn%2F%2B740%3D","updated":"2013-08-11 09:44:46.000000000","message":"@Sandy Walsh:\n\nIf marker got None, which means sqlalchemy_utils.paginate_query function got marker\u003dNone passed in, the user will get the limit number of results with sort direction and sort keys.","commit_id":"71de746a5a624d71fade200da2f4a31c3efbf0e4"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"b03016acd8df1bfc1cb190a63de225319f1bb6ab","unresolved":false,"context_lines":[{"line_number":252,"context_line":""},{"line_number":253,"context_line":"        :param session: SQLAlchemy session."},{"line_number":254,"context_line":"        :param model: ORM model class that need be query."},{"line_number":255,"context_line":"        :param maker_pair: Attribute-value pair filter."},{"line_number":256,"context_line":"        \"\"\""},{"line_number":257,"context_line":"        if not (model and marker_pair):"},{"line_number":258,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAARH%2F%2F6Kg%3D","line":255,"updated":"2013-08-15 12:15:22.000000000","message":"marker pair","commit_id":"a19f1b1ec152256488839e64008779cf9eff7af7"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"b03016acd8df1bfc1cb190a63de225319f1bb6ab","unresolved":false,"context_lines":[{"line_number":261,"context_line":"        for key, value in marker_pair.iteritems():"},{"line_number":262,"context_line":"            key_attr \u003d getattr(model, key)"},{"line_number":263,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":264,"context_line":"        query \u003d query.limit(2)"},{"line_number":265,"context_line":"        if query.count() \u003c\u003d 0:"},{"line_number":266,"context_line":"            raise base.NoResultFound"},{"line_number":267,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAARH%2F%2F6Kc%3D","line":264,"updated":"2013-08-15 12:15:22.000000000","message":"you can limit(1) no?","commit_id":"a19f1b1ec152256488839e64008779cf9eff7af7"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"b03016acd8df1bfc1cb190a63de225319f1bb6ab","unresolved":false,"context_lines":[{"line_number":341,"context_line":"        if metaquery:"},{"line_number":342,"context_line":"            raise NotImplementedError(\u0027metaquery not implemented\u0027)"},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"        marker \u003d Connection._get_marker(session, Meter, marker_pair)"},{"line_number":345,"context_line":"        sort_keys \u003d base._handle_sort_key(\u0027resource\u0027, sort_key)"},{"line_number":346,"context_line":""},{"line_number":347,"context_line":"        query \u003d sqlalchemy_utils.paginate_query(query, Meter, limit\u003dlimit,"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAARH%2F%2F6KY%3D","line":344,"updated":"2013-08-15 12:15:22.000000000","message":"s/Connection/self/ and remove static method in this case.","commit_id":"a19f1b1ec152256488839e64008779cf9eff7af7"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"b03016acd8df1bfc1cb190a63de225319f1bb6ab","unresolved":false,"context_lines":[{"line_number":421,"context_line":"        if metaquery:"},{"line_number":422,"context_line":"            raise NotImplementedError(\u0027metaquery not implemented\u0027)"},{"line_number":423,"context_line":""},{"line_number":424,"context_line":"        marker \u003d Connection._get_marker(session, Resource, marker_pair)"},{"line_number":425,"context_line":"        sort_keys \u003d base._handle_sort_key(\u0027meter\u0027, sort_key)"},{"line_number":426,"context_line":""},{"line_number":427,"context_line":"        query \u003d sqlalchemy_utils.paginate_query(query, Resource, limit\u003dlimit,"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAARH%2F%2F6KQ%3D","line":424,"updated":"2013-08-15 12:15:22.000000000","message":"s/Connection/self/","commit_id":"a19f1b1ec152256488839e64008779cf9eff7af7"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"b03016acd8df1bfc1cb190a63de225319f1bb6ab","unresolved":false,"context_lines":[{"line_number":610,"context_line":"        if alarm_id is not None:"},{"line_number":611,"context_line":"            query \u003d query.filter(Alarm.id \u003d\u003d alarm_id)"},{"line_number":612,"context_line":""},{"line_number":613,"context_line":"        marker \u003d Connection._get_marker(session, Alarm, marker_pair)"},{"line_number":614,"context_line":"        sort_keys \u003d base._handle_sort_key(\u0027alarm\u0027, sort_key)"},{"line_number":615,"context_line":""},{"line_number":616,"context_line":"        query \u003d sqlalchemy_utils.paginate_query(query, Alarm, limit\u003dlimit,"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAARH%2F%2F6KM%3D","line":613,"updated":"2013-08-15 12:15:22.000000000","message":"s/Connection/self/","commit_id":"a19f1b1ec152256488839e64008779cf9eff7af7"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"20eadb90f05e354e823ede57817d1de6ecce6f8c","unresolved":false,"context_lines":[{"line_number":258,"context_line":"            return"},{"line_number":259,"context_line":"        query \u003d session.query(model)"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"        for key, value in marker_pair.iteritems():"},{"line_number":262,"context_line":"            key_attr \u003d getattr(model, key)"},{"line_number":263,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":264,"context_line":"        query \u003d query.limit(1)"}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAASX%2F%2F6m8%3D","line":261,"updated":"2013-08-23 19:45:36.000000000","message":"i believe iteritems() is gone in python3. consider using something else.","commit_id":"8d081191ecda8cedab6a90c1746203dff82fa657"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"2ffd9f3e14caa996928fbdc4bc76e2b668d8876a","unresolved":false,"context_lines":[{"line_number":247,"context_line":"        query.delete(synchronize_session\u003d\u0027fetch\u0027)"},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"    @staticmethod"},{"line_number":250,"context_line":"    def _get_marker(session, model, marker_pair):"},{"line_number":251,"context_line":"        \"\"\"Return the mark object according to the key-value pair."},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"        :param session: SQLAlchemy session."}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAASX%2F%2F1KA%3D","line":250,"updated":"2013-08-26 16:39:44.000000000","message":"See previous comments about marker_pair... There should just be a marker *value*, not a marker pair... The marker field is ALWAYS the primary key of the base table.","commit_id":"b6b247172802a4d3e2c4d4558c9b241a2892a126"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"2ffd9f3e14caa996928fbdc4bc76e2b668d8876a","unresolved":false,"context_lines":[{"line_number":265,"context_line":"        if query.count() \u003c\u003d 0:"},{"line_number":266,"context_line":"            raise base.NoResultFound"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        return query.one()"},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"    @staticmethod"},{"line_number":271,"context_line":"    def get_users(source\u003dNone):"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAASX%2F%2F1KQ%3D","line":268,"updated":"2013-08-26 16:39:44.000000000","message":"There should be no querying needed to get a marker. It should be passed in from the caller/client.","commit_id":"b6b247172802a4d3e2c4d4558c9b241a2892a126"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"b39d55674d36bd629368a67ffb75c0c709c1af14","unresolved":false,"context_lines":[{"line_number":265,"context_line":"        if query.count() \u003c\u003d 0:"},{"line_number":266,"context_line":"            raise base.NoResultFound"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        return query.one()"},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"    @staticmethod"},{"line_number":271,"context_line":"    def get_users(source\u003dNone):"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAASn%2F%2F%2Bo4%3D","line":268,"in_reply_to":"AAAASX%2F%2F0jg%3D","updated":"2013-08-27 09:14:52.000000000","message":"if we just pass the marker value in, what need we do when the sort key is not the primary key?","commit_id":"b6b247172802a4d3e2c4d4558c9b241a2892a126"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"b0aa592af1097a44824511219ed7726a3ca344b2","unresolved":false,"context_lines":[{"line_number":265,"context_line":"        if query.count() \u003c\u003d 0:"},{"line_number":266,"context_line":"            raise base.NoResultFound"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        return query.one()"},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"    @staticmethod"},{"line_number":271,"context_line":"    def get_users(source\u003dNone):"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAASX%2F%2F0jg%3D","line":268,"in_reply_to":"AAAASX%2F%2F0l8%3D","updated":"2013-08-26 19:19:45.000000000","message":"I don\u0027t see why you\u0027d want to do an extra lookup to see if a marker value exists in the database. The only way it would is if the caller was mucking with the marker value manually, and there\u0027s no harm in just passing in the marker value as-is to the query, as it will just be injected like so:\n\n WHERE id \u003e :marker","commit_id":"b6b247172802a4d3e2c4d4558c9b241a2892a126"},{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"c2a2e16ff9c4d4e757330cdcff55f038e65152c7","unresolved":false,"context_lines":[{"line_number":265,"context_line":"        if query.count() \u003c\u003d 0:"},{"line_number":266,"context_line":"            raise base.NoResultFound"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        return query.one()"},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"    @staticmethod"},{"line_number":271,"context_line":"    def get_users(source\u003dNone):"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAASX%2F%2F0l8%3D","line":268,"in_reply_to":"AAAASX%2F%2F1KQ%3D","updated":"2013-08-26 19:09:23.000000000","message":"I thought this was just to check that there were results, but wouldn\u0027t that be handled by sqlalchemy_utils?","commit_id":"b6b247172802a4d3e2c4d4558c9b241a2892a126"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"c4012d11ab31144273162b468251e2363e849b7c","unresolved":false,"context_lines":[{"line_number":265,"context_line":"        if query.count() \u003c\u003d 0:"},{"line_number":266,"context_line":"            raise base.NoResultFound"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        return query.one()"},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"    @staticmethod"},{"line_number":271,"context_line":"    def get_users(source\u003dNone):"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAASn%2F%2F96A%3D","line":268,"in_reply_to":"AAAASn%2F%2F%2BKw%3D","updated":"2013-08-27 12:56:43.000000000","message":"sure, the primary key should be the first one in sort keys.  And we are talking about if we should pass marker_value directly into paginate_query function without using get_marker function. \n\n\nI think the get_marker function is necessary here because user may pass in their own sort keys.","commit_id":"b6b247172802a4d3e2c4d4558c9b241a2892a126"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"b10b618e4436a295f140d3c703489543a8ad4db9","unresolved":false,"context_lines":[{"line_number":265,"context_line":"        if query.count() \u003c\u003d 0:"},{"line_number":266,"context_line":"            raise base.NoResultFound"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        return query.one()"},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"    @staticmethod"},{"line_number":271,"context_line":"    def get_users(source\u003dNone):"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAASn%2F%2F%2BKw%3D","line":268,"in_reply_to":"AAAASn%2F%2F%2Bo4%3D","updated":"2013-08-27 11:42:04.000000000","message":"We\u0027re going to have to enforce sorting on the same key we use for the marker, at a minimum. Any sort keys provided by the user will have to come after that. Otherwise we can\u0027t ensure a consistent order for the marker keys and they won\u0027t be meaningful.","commit_id":"b6b247172802a4d3e2c4d4558c9b241a2892a126"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"417967ce5281b1315c79a81e30c315a9accf3655","unresolved":false,"context_lines":[{"line_number":267,"context_line":"            key_attr \u003d getattr(model, key)"},{"line_number":268,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":269,"context_line":"        query \u003d query.limit(1)"},{"line_number":270,"context_line":"        if query.count() \u003c\u003d 0:"},{"line_number":271,"context_line":"            raise base.NoResultFound"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"        return query.one()"}],"source_content_type":"text/x-python","patch_set":33,"id":"AAAASn%2F%2FplA%3D","line":270,"updated":"2013-09-01 14:46:47.000000000","message":"This is going to result in querying twice, won\u0027t it? Once to get the count, and a second time to get the row. The one() method raises an exception if the result set has 0 or \u003e1 items in it, so catching that exception should be more efficient than checking the count directly. http://docs.sqlalchemy.org/en/rel_0_7/orm/query.html#sqlalchemy.orm.query.Query.one","commit_id":"d0fa126ef096585fb915561b22ae2db054421c06"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"498d0fa9c15861eef5d680949e444967c54932ae","unresolved":false,"context_lines":[{"line_number":267,"context_line":"            key_attr \u003d getattr(model, key)"},{"line_number":268,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":269,"context_line":"        query \u003d query.limit(1)"},{"line_number":270,"context_line":"        if query.count() \u003c\u003d 0:"},{"line_number":271,"context_line":"            raise base.NoResultFound"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"        return query.one()"}],"source_content_type":"text/x-python","patch_set":33,"id":"AAAASn%2F%2Fokk%3D","line":270,"in_reply_to":"AAAASn%2F%2FplA%3D","updated":"2013-09-02 07:42:14.000000000","message":"Done","commit_id":"d0fa126ef096585fb915561b22ae2db054421c06"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"513a967539a4aa81cde2806e9cdd89c7f674cbbd","unresolved":false,"context_lines":[{"line_number":262,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":263,"context_line":"        query \u003d query.limit(1)"},{"line_number":264,"context_line":"        try:"},{"line_number":265,"context_line":"            ret \u003d query.one()"},{"line_number":266,"context_line":"        except sqlalchemy.orm.exc.NoResultFound:"},{"line_number":267,"context_line":"            raise base.NoResultFound"},{"line_number":268,"context_line":""}],"source_content_type":"text/x-python","patch_set":37,"id":"AAAASn%2F%2Fjs4%3D","line":265,"updated":"2013-09-03 14:37:18.000000000","message":"I just don\u0027t understand this, sorry... The marker is a value that should be supplied by the user. There should not be a need to look up the marker in a database.","commit_id":"64e37c7da64b87c504da0b74a56c590f87a2d861"},{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"c0d190e4f899c10678166ee7c9bafa56b63f831c","unresolved":false,"context_lines":[{"line_number":262,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":263,"context_line":"        query \u003d query.limit(1)"},{"line_number":264,"context_line":"        try:"},{"line_number":265,"context_line":"            ret \u003d query.one()"},{"line_number":266,"context_line":"        except sqlalchemy.orm.exc.NoResultFound:"},{"line_number":267,"context_line":"            raise base.NoResultFound"},{"line_number":268,"context_line":""}],"source_content_type":"text/x-python","patch_set":37,"id":"AAAASn%2F%2FcLY%3D","line":265,"in_reply_to":"AAAASn%2F%2FfTE%3D","updated":"2013-09-04 18:18:27.000000000","message":"*thank you* ... this was the code that started this whole thing for me in the first place. :)\n\nthe data passed to and returned from the client should be full markers (key, value and operator) and not just marker values. I believe utils.py will work with that fine (last I looked :)","commit_id":"64e37c7da64b87c504da0b74a56c590f87a2d861"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"e51cccfb899699da2f0dd938c10ce19703b737c4","unresolved":false,"context_lines":[{"line_number":262,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":263,"context_line":"        query \u003d query.limit(1)"},{"line_number":264,"context_line":"        try:"},{"line_number":265,"context_line":"            ret \u003d query.one()"},{"line_number":266,"context_line":"        except sqlalchemy.orm.exc.NoResultFound:"},{"line_number":267,"context_line":"            raise base.NoResultFound"},{"line_number":268,"context_line":""}],"source_content_type":"text/x-python","patch_set":37,"id":"AAAASn%2F%2FfTE%3D","line":265,"in_reply_to":"AAAASn%2F%2FikI%3D","updated":"2013-09-04 09:26:42.000000000","message":"i got you:). get_marker should be removed here. but i have other questions for this.\n\n\n1) As you can see, i  am using the paginate_query methods of openstack/common/db/sqlalchemy/utils.py without developing our own method. \nIn that method, it require a marker not marker_value. \n\n\n2)  If i remove the get_marker, does it still make sense to let users to pass sort keys besides the primary key?  because marker_value is only the value of primary key. \n\n\n\nThanks\n\nFengqian","commit_id":"64e37c7da64b87c504da0b74a56c590f87a2d861"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"882864e5d713ed9c3678a7ecee46131912a9d2e0","unresolved":false,"context_lines":[{"line_number":262,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":263,"context_line":"        query \u003d query.limit(1)"},{"line_number":264,"context_line":"        try:"},{"line_number":265,"context_line":"            ret \u003d query.one()"},{"line_number":266,"context_line":"        except sqlalchemy.orm.exc.NoResultFound:"},{"line_number":267,"context_line":"            raise base.NoResultFound"},{"line_number":268,"context_line":""}],"source_content_type":"text/x-python","patch_set":37,"id":"AAAASn%2F%2FikI%3D","line":265,"in_reply_to":"AAAASn%2F%2FjcM%3D","updated":"2013-09-03 17:50:46.000000000","message":"You do not need to query the database for those values. They are supplied by the caller. You should be able to construct the query accordingly without doing a separate query for a marker record.","commit_id":"64e37c7da64b87c504da0b74a56c590f87a2d861"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"f787044eae711814214e1cdb90aaaa930557f356","unresolved":false,"context_lines":[{"line_number":262,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":263,"context_line":"        query \u003d query.limit(1)"},{"line_number":264,"context_line":"        try:"},{"line_number":265,"context_line":"            ret \u003d query.one()"},{"line_number":266,"context_line":"        except sqlalchemy.orm.exc.NoResultFound:"},{"line_number":267,"context_line":"            raise base.NoResultFound"},{"line_number":268,"context_line":""}],"source_content_type":"text/x-python","patch_set":37,"id":"AAAASn%2F%2FjcM%3D","line":265,"in_reply_to":"AAAASn%2F%2Fjs4%3D","updated":"2013-09-03 15:29:37.000000000","message":"yes, for the database has unique sort_key, which means each object can be identify by one attribute, there is no need to look up the marker again in database. The query criteria is very simple, sort_key \u003c marker_value.\n\n\nBut if the sort_key is not unique, take the Meter for example, we have to take two keys, resource_id and meter_name as a combination sort_keys for the pagination query.  Then we need to build query criteria like this:\n\n\n(resource_id \u003c marker.resource_id) or (resource_id \u003dmarker.resource_id and meter_name \u003c marker.meter_name)\n\n\nIn this situation, we need to find marker in order to get the value of each field.\n\n\nThanks\n\n\nFengqian","commit_id":"64e37c7da64b87c504da0b74a56c590f87a2d861"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"962420837e97a50f6c50daa8682ed6e78ac699cf","unresolved":false,"context_lines":[{"line_number":276,"context_line":"        if key_transfer:"},{"line_number":277,"context_line":"            primary_keys \u003d cls.keys_translate(primary_keys, model_name)"},{"line_number":278,"context_line":"        if value_decoding:"},{"line_number":279,"context_line":"            marker_value \u003d api_models.Meter.get_marker_values(marker_value)"},{"line_number":280,"context_line":"        else:"},{"line_number":281,"context_line":"            marker_value \u003d [marker_value]"},{"line_number":282,"context_line":""}],"source_content_type":"text/x-python","patch_set":42,"id":"AAAATX%2F%2F%2FUQ%3D","line":279,"updated":"2013-10-23 08:17:52.000000000","message":"Can we use api_model.get_marker_values() here to support future other model which supports get_marker_values?","commit_id":"8552076b723868b38499608a956eae6d0e642240"},{"author":{"_account_id":5313,"name":"David Peraza","email":"david_peraza@persistentsys.com","username":"dperaza"},"change_message_id":"c7d0b34d9515c3fa992cde010765b3b1fcc203a0","unresolved":false,"context_lines":[{"line_number":34,"context_line":"from ceilometer.openstack.common import log"},{"line_number":35,"context_line":"from ceilometer.openstack.common import timeutils"},{"line_number":36,"context_line":"from ceilometer.storage import base"},{"line_number":37,"context_line":"from ceilometer.storage.base import Pagination"},{"line_number":38,"context_line":"from ceilometer.storage import models as api_models"},{"line_number":39,"context_line":"from ceilometer.storage.sqlalchemy import migration"},{"line_number":40,"context_line":"from ceilometer.storage.sqlalchemy.models import Alarm"}],"source_content_type":"text/x-python","patch_set":43,"id":"AAAATn%2F%2Fzdg%3D","line":37,"updated":"2013-10-28 19:46:48.000000000","message":"I gather is acceptable to import classes directly in ceilometer project","commit_id":"2ef3a7cb27cc6a011d31e94f35a2926f596a740d"},{"author":{"_account_id":5313,"name":"David Peraza","email":"david_peraza@persistentsys.com","username":"dperaza"},"change_message_id":"c7d0b34d9515c3fa992cde010765b3b1fcc203a0","unresolved":false,"context_lines":[{"line_number":281,"context_line":"            marker_value \u003d [marker_value]"},{"line_number":282,"context_line":""},{"line_number":283,"context_line":"        query \u003d session.query(model)"},{"line_number":284,"context_line":"        for key, value in zip(primary_keys, marker_value):"},{"line_number":285,"context_line":"            key_attr \u003d getattr(model, key)"},{"line_number":286,"context_line":"            query \u003d query.filter(key_attr \u003d\u003d value)"},{"line_number":287,"context_line":"        query \u003d query.limit(1)"}],"source_content_type":"text/x-python","patch_set":43,"id":"AAAATn%2F%2Fzc8%3D","line":284,"updated":"2013-10-28 19:46:48.000000000","message":"recommend using http://docs.python.org/2/library/itertools.html#itertools.izip so that there is not extra copies.","commit_id":"2ef3a7cb27cc6a011d31e94f35a2926f596a740d"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"88811016aa3912d199c63028c6b59fbb10e59d54","unresolved":false,"context_lines":[{"line_number":374,"context_line":"        if value_decoding:"},{"line_number":375,"context_line":"            marker_value \u003d base.split_combined_marker_values(marker_value)"},{"line_number":376,"context_line":"        else:"},{"line_number":377,"context_line":"            marker_value \u003d [marker_value]"},{"line_number":378,"context_line":""},{"line_number":379,"context_line":"        query \u003d session.query(model)"},{"line_number":380,"context_line":"        for key, value in itertools.izip(primary_keys, marker_value):"}],"source_content_type":"text/x-python","patch_set":49,"id":"AAAAUH%2F%2FFoQ%3D","line":377,"updated":"2014-01-17 15:37:48.000000000","message":"value_decoding parameter is no longer necessary, nor are lines 376-377. This should be all that is needed:\n\n marker_value \u003d base.split_combined_marker_values(marker_value)","commit_id":"6170981c8c99b20548659672d1e21a957ae1cecc"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"88811016aa3912d199c63028c6b59fbb10e59d54","unresolved":false,"context_lines":[{"line_number":503,"context_line":"        else:"},{"line_number":504,"context_line":"            limit, marker_value, sort_keys, sort_dirs \u003d\\"},{"line_number":505,"context_line":"                base.Pagination.default_pagination_parameters("},{"line_number":506,"context_line":"                    api_models.Resource)"},{"line_number":507,"context_line":""},{"line_number":508,"context_line":"        marker \u003d self._get_marker(session\u003dsession, model\u003dmodels.Meter,"},{"line_number":509,"context_line":"                                  api_model\u003dapi_models.Resource,"}],"source_content_type":"text/x-python","patch_set":49,"id":"AAAAUH%2F%2FFj8%3D","line":506,"updated":"2014-01-17 15:37:48.000000000","message":"Here, we need to add assurance that sort_keys contains at least one unique column, so perhaps do something like this:\n\n # Ensure we have at least one unique column in sort_keys. Look at supplied\n # sort keys, and if no unique column, simply append the primary key column(s)\n # of the model to the list of sort keys, using an ascending sort.\n need_unique_sort \u003d True\n for sk in sort_keys:\n     if model.c[sk].unique:\n         need_unique_sort \u003d False\n if need_unique_sort:\n     pk_cols \u003d model.__mapper__.primary_key\n     sort_keys.append([c.name for c in pk_cols])\n     sort_dirs.append([\u0027asc\u0027 for c in pk_cols])","commit_id":"6170981c8c99b20548659672d1e21a957ae1cecc"}],"tests/storage/base.py":[{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"6502a2b67b0054c26801d0aa3322d2b32c83609a","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        try:"},{"line_number":353,"context_line":"            results \u003d list(self.conn.get_resources(marker_pairs\u003dmarker_pairs))"},{"line_number":354,"context_line":"            self.assertEqual(len(results), 1)"},{"line_number":355,"context_line":"        except NoResultFound:"},{"line_number":356,"context_line":"            self.assertTrue(True)"},{"line_number":357,"context_line":""},{"line_number":358,"context_line":"    def test_get_resources_marker_multipe(self):"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAQ3%2F%2F5WE%3D","line":355,"updated":"2013-08-13 10:19:46.000000000","message":"Agreed this test looks suspicious. If it fails for a backend, there\u0027s something wrong anyway.","commit_id":"214362a689a1068e5d16a6d79d9166aa2158df53"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"6770b4c74e3fc6a4190ab59ddff9ef0915a0c4a1","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        try:"},{"line_number":353,"context_line":"            results \u003d list(self.conn.get_resources(marker_pairs\u003dmarker_pairs))"},{"line_number":354,"context_line":"            self.assertEqual(len(results), 1)"},{"line_number":355,"context_line":"        except NoResultFound:"},{"line_number":356,"context_line":"            self.assertTrue(True)"},{"line_number":357,"context_line":""},{"line_number":358,"context_line":"    def test_get_resources_marker_multipe(self):"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAQ3%2F%2F9Bo%3D","line":355,"updated":"2013-08-12 15:12:59.000000000","message":"please use self.assertRaises() in such cases","commit_id":"214362a689a1068e5d16a6d79d9166aa2158df53"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"8ababc5334824d9d8a798cb25f1ddf556e421202","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        try:"},{"line_number":353,"context_line":"            results \u003d list(self.conn.get_resources(marker_pairs\u003dmarker_pairs))"},{"line_number":354,"context_line":"            self.assertEqual(len(results), 1)"},{"line_number":355,"context_line":"        except NoResultFound:"},{"line_number":356,"context_line":"            self.assertTrue(True)"},{"line_number":357,"context_line":""},{"line_number":358,"context_line":"    def test_get_resources_marker_multipe(self):"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAQ3%2F%2F5IA%3D","line":355,"in_reply_to":"AAAAQ3%2F%2F5WE%3D","updated":"2013-08-13 11:30:49.000000000","message":"One thing i need to clarify is that i made a mistake here. self.assertRaises() could not work for both backends, not just mongodb, I just rechecked.\n\n\nThere must be something wrong, i know, but it should not related to this patch.  The previous test case test_get_resources_by_metaquery() already added comments about this problem. \n\n\nTest cases here also looks weired to me, but now i have to work around here.\nIf we want to fix, it should be another independent patch, so what is your suggestion?\n\nTHanks\n\n\nFengqian","commit_id":"214362a689a1068e5d16a6d79d9166aa2158df53"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"51d0058c0f0e2b0a810aa02034487b71a481e47a","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        try:"},{"line_number":353,"context_line":"            results \u003d list(self.conn.get_resources(marker_pairs\u003dmarker_pairs))"},{"line_number":354,"context_line":"            self.assertEqual(len(results), 1)"},{"line_number":355,"context_line":"        except NoResultFound:"},{"line_number":356,"context_line":"            self.assertTrue(True)"},{"line_number":357,"context_line":""},{"line_number":358,"context_line":"    def test_get_resources_marker_multipe(self):"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAQ3%2F%2F5wM%3D","line":355,"in_reply_to":"AAAAQ3%2F%2F818%3D","updated":"2013-08-13 08:26:16.000000000","message":"Thanks, got it. But it\u0027s looks strange for me...","commit_id":"214362a689a1068e5d16a6d79d9166aa2158df53"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"af0660570ce24dbc1b3f2c60d8863c5d6cff46b6","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        try:"},{"line_number":353,"context_line":"            results \u003d list(self.conn.get_resources(marker_pairs\u003dmarker_pairs))"},{"line_number":354,"context_line":"            self.assertEqual(len(results), 1)"},{"line_number":355,"context_line":"        except NoResultFound:"},{"line_number":356,"context_line":"            self.assertTrue(True)"},{"line_number":357,"context_line":""},{"line_number":358,"context_line":"    def test_get_resources_marker_multipe(self):"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAQ3%2F%2F818%3D","line":355,"in_reply_to":"AAAAQ3%2F%2F9Bo%3D","updated":"2013-08-12 16:00:58.000000000","message":"Actually, i used self.assertRaises() at first,  but it does not work for mongodb backend while work normal for sqlalchemy. And it worked when i used try+except. It is weired here.\n\nThanks\n\n\nFengqian","commit_id":"214362a689a1068e5d16a6d79d9166aa2158df53"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"1469eb2215ad9f50f958caf44cd2f37da85572b0","unresolved":false,"context_lines":[{"line_number":350,"context_line":"        marker_pair \u003d {\u0027user_id\u0027: \u0027user-id-foo\u0027}"},{"line_number":351,"context_line":"        try:"},{"line_number":352,"context_line":"            results \u003d list(self.conn.get_resources(marker_pair\u003dmarker_pair))"},{"line_number":353,"context_line":"            self.assertEqual(len(results), 1)"},{"line_number":354,"context_line":"        except NoResultFound:"},{"line_number":355,"context_line":"            self.assertTrue(True)"},{"line_number":356,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAARH%2F%2F6xY%3D","line":353,"updated":"2013-08-15 08:00:16.000000000","message":"Should make sure it never reaches here","commit_id":"129631dfdbfe20cdd53fce643482b6ff85a651b2"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"1469eb2215ad9f50f958caf44cd2f37da85572b0","unresolved":false,"context_lines":[{"line_number":1074,"context_line":"        marker_pair \u003d {\u0027name\u0027: \u0027user-id-foo\u0027}"},{"line_number":1075,"context_line":"        try:"},{"line_number":1076,"context_line":"            results \u003d list(self.conn.get_alarms(marker_pair\u003dmarker_pair))"},{"line_number":1077,"context_line":"            self.assertEqual(len(results), 1)"},{"line_number":1078,"context_line":"        except NoResultFound:"},{"line_number":1079,"context_line":"            self.assertTrue(True)"},{"line_number":1080,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAARH%2F%2F6xU%3D","line":1077,"updated":"2013-08-15 08:00:16.000000000","message":"Should make sure it never reaches here","commit_id":"129631dfdbfe20cdd53fce643482b6ff85a651b2"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"b03016acd8df1bfc1cb190a63de225319f1bb6ab","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        #                  self.conn.get_resources,"},{"line_number":353,"context_line":"        #                  marker_pair\u003dmarker_pair)"},{"line_number":354,"context_line":"        #Above code did not work here. Just use try+except to"},{"line_number":355,"context_line":"        #work around. Same reason to below test cases."},{"line_number":356,"context_line":"        try:"},{"line_number":357,"context_line":"            results \u003d list(self.conn.get_resources(marker_pair\u003dmarker_pair))"},{"line_number":358,"context_line":"            self.fail(\"Something is wrong if you see this\")"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAARH%2F%2F6KA%3D","line":355,"updated":"2013-08-15 12:15:22.000000000","message":"Could we have the reason it doesn\u0027t work? If that doesn\u0027t work, that sounds like a potential problem in the code somewhere.","commit_id":"a19f1b1ec152256488839e64008779cf9eff7af7"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"d85a502e3aeb0f8db0b949d7c8774bf2bb9a18bd","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        #                  self.conn.get_resources,"},{"line_number":353,"context_line":"        #                  marker_pair\u003dmarker_pair)"},{"line_number":354,"context_line":"        #Above code did not work here. Just use try+except to"},{"line_number":355,"context_line":"        #work around. Same reason to below test cases."},{"line_number":356,"context_line":"        try:"},{"line_number":357,"context_line":"            results \u003d list(self.conn.get_resources(marker_pair\u003dmarker_pair))"},{"line_number":358,"context_line":"            self.fail(\"Something is wrong if you see this\")"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAARH%2F%2F5x0%3D","line":355,"in_reply_to":"AAAARH%2F%2F6KA%3D","updated":"2013-08-15 14:02:51.000000000","message":"yes, it looks like another bug of test tools. As to the reason, Please see the comment of line 329, seems that someone already found the problem here.\n\nI think we can just work around here for temporary, ok? :)\n\nThanks\n\n\nFengqian","commit_id":"a19f1b1ec152256488839e64008779cf9eff7af7"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"20eadb90f05e354e823ede57817d1de6ecce6f8c","unresolved":false,"context_lines":[{"line_number":356,"context_line":"        #                  self.conn.get_resources,"},{"line_number":357,"context_line":"        #                  marker_pair\u003dmarker_pair)"},{"line_number":358,"context_line":"        #Above code did not work here. Just use try+except to"},{"line_number":359,"context_line":"        #work around. Same reason to below test cases."},{"line_number":360,"context_line":"        try:"},{"line_number":361,"context_line":"            results \u003d list(self.conn.get_resources(pagination\u003dpagination))"},{"line_number":362,"context_line":"            self.fail(\"Something is wrong if you see this\")"}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAASX%2F%2F6iA%3D","line":359,"updated":"2013-08-23 19:45:36.000000000","message":"this workaround looks odd. i\u0027m interested why it didn\u0027t work. i noticed your commented out code uses self.conn.get_resources(marker_pair\u003dmarker_pair) is that a copy/paste issue? shouldn\u0027t it be self.conn.get_resources(pagination\u003dpagination) like you have below?","commit_id":"8d081191ecda8cedab6a90c1746203dff82fa657"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"77b5a38e43b60818c449de846bd85e45aa20f377","unresolved":false,"context_lines":[{"line_number":356,"context_line":"        #                  self.conn.get_resources,"},{"line_number":357,"context_line":"        #                  marker_pair\u003dmarker_pair)"},{"line_number":358,"context_line":"        #Above code did not work here. Just use try+except to"},{"line_number":359,"context_line":"        #work around. Same reason to below test cases."},{"line_number":360,"context_line":"        try:"},{"line_number":361,"context_line":"            results \u003d list(self.conn.get_resources(pagination\u003dpagination))"},{"line_number":362,"context_line":"            self.fail(\"Something is wrong if you see this\")"}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAASX%2F%2F3dc%3D","line":359,"in_reply_to":"AAAASX%2F%2F6iA%3D","updated":"2013-08-26 01:08:15.000000000","message":"There is a typo in my comments:). i debug this issue and get some info here. \n\nI found that unless i wrapped get_resources with list operation, assertRaises will not work here. I think it may because the \"yield \" operation in get_resources, it will return a generator.\n\n\nYou can see my latest patch set.\n\n\nThanks\n\n\nFengqian","commit_id":"8d081191ecda8cedab6a90c1746203dff82fa657"}],"tests/storage/test_impl_sqlalchemy.py":[{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"417967ce5281b1315c79a81e30c315a9accf3655","unresolved":false,"context_lines":[{"line_number":35,"context_line":"class SQLAlchemyConnection(tests_db.TestBase):"},{"line_number":36,"context_line":"    database_connection \u003d \u0027sqlite://\u0027"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def test_get_primary_sort_key(self):"},{"line_number":39,"context_line":"        sort_key \u003d impl_sqlalchemy.Connection.get_primary_sort_key(\u0027alarm\u0027)"},{"line_number":40,"context_line":"        self.assertEqual(sort_key, \u0027id\u0027)"},{"line_number":41,"context_line":"        sort_key \u003d impl_sqlalchemy.Connection.get_primary_sort_key(\u0027resource\u0027)"}],"source_content_type":"text/x-python","patch_set":33,"id":"AAAASn%2F%2FplE%3D","line":38,"updated":"2013-09-01 14:46:47.000000000","message":"Meter is a special case, since it returns multiple items. It should be tested, too.","commit_id":"d0fa126ef096585fb915561b22ae2db054421c06"}]}
