)]}'
{"neutron/objects/trunk.py":[{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"39509c721f5e29f3a4cddf8e59b31cd333a8d787","unresolved":false,"context_lines":[{"line_number":50,"context_line":"                if ex.key_table is None:"},{"line_number":51,"context_line":"                    # workaround for sqlite as the exception does not contain"},{"line_number":52,"context_line":"                    # the required details"},{"line_number":53,"context_line":"                    if not Trunk.get_object(self._context, id\u003dself.trunk_id):"},{"line_number":54,"context_line":"                        ex.key_table \u003d Trunk.db_model.__tablename__"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"                if ex.key_table \u003d\u003d Trunk.db_model.__tablename__:"}],"source_content_type":"text/x-python","patch_set":3,"id":"7aa08908_93077e17","line":53,"updated":"2016-06-07 16:26:16.000000000","message":"Special-casing just for sqlite makes me sad :( I guess we do what we have to do.","commit_id":"8f6afaf06f3f1a409f047c6263c30cf0cdaeb5eb"},{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"ce2c5c2a5aa4a3d51903e0061e57deb8a31da6d3","unresolved":false,"context_lines":[{"line_number":50,"context_line":"                if ex.key_table is None:"},{"line_number":51,"context_line":"                    # workaround for sqlite as the exception does not contain"},{"line_number":52,"context_line":"                    # the required details"},{"line_number":53,"context_line":"                    if not Trunk.get_object(self._context, id\u003dself.trunk_id):"},{"line_number":54,"context_line":"                        ex.key_table \u003d Trunk.db_model.__tablename__"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"                if ex.key_table \u003d\u003d Trunk.db_model.__tablename__:"}],"source_content_type":"text/x-python","patch_set":3,"id":"7aa08908_7e9c565d","line":53,"in_reply_to":"7aa08908_28a9f424","updated":"2016-06-07 17:26:20.000000000","message":"Like I said, we should do what we have to do. It\u0027s just annoying that there\u0027s not a consistent way to handle these situations.","commit_id":"8f6afaf06f3f1a409f047c6263c30cf0cdaeb5eb"},{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"7ccaa8a7bd9a52f060cd8d689a1dfde1e932ad6c","unresolved":false,"context_lines":[{"line_number":50,"context_line":"                if ex.key_table is None:"},{"line_number":51,"context_line":"                    # workaround for sqlite as the exception does not contain"},{"line_number":52,"context_line":"                    # the required details"},{"line_number":53,"context_line":"                    if not Trunk.get_object(self._context, id\u003dself.trunk_id):"},{"line_number":54,"context_line":"                        ex.key_table \u003d Trunk.db_model.__tablename__"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"                if ex.key_table \u003d\u003d Trunk.db_model.__tablename__:"}],"source_content_type":"text/x-python","patch_set":3,"id":"7aa08908_63453916","line":53,"in_reply_to":"7aa08908_7e9c565d","updated":"2016-06-09 23:20:42.000000000","message":"I\u0027m glad it is only the comment that says sqlite.  If it were something like this, I\u0027d like it less:\n\n  if DB is \u0027sqlite\u0027:\n      do_special_stuff()","commit_id":"8f6afaf06f3f1a409f047c6263c30cf0cdaeb5eb"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"9eb5296cab5cd42fc7c1494d6f4450db48b6dcd4","unresolved":false,"context_lines":[{"line_number":50,"context_line":"                if ex.key_table is None:"},{"line_number":51,"context_line":"                    # workaround for sqlite as the exception does not contain"},{"line_number":52,"context_line":"                    # the required details"},{"line_number":53,"context_line":"                    if not Trunk.get_object(self._context, id\u003dself.trunk_id):"},{"line_number":54,"context_line":"                        ex.key_table \u003d Trunk.db_model.__tablename__"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"                if ex.key_table \u003d\u003d Trunk.db_model.__tablename__:"}],"source_content_type":"text/x-python","patch_set":3,"id":"7aa08908_28a9f424","line":53,"in_reply_to":"7aa08908_93077e17","updated":"2016-06-07 17:02:13.000000000","message":"Technically it\u0027s for any DB backend that does not care to provide \u0027key_table\u0027, which happens to be \u0027sqlite\u0027 :)\n\nI\u0027d gladly remove that if anyone has a better suggestion. But looking at [1] I\u0027m not sure if it is possible.\n\n[1] https://github.com/openstack/oslo.db/blob/3fadd5af3d4869b6df2170ea80e3ea448fddfb96/oslo_db/sqlalchemy/exc_filters.py#L203","commit_id":"8f6afaf06f3f1a409f047c6263c30cf0cdaeb5eb"},{"author":{"_account_id":6788,"name":"Rossella Sblendido","email":"rsblendido@suse.com","username":"rossella-o"},"change_message_id":"1e0e498633fe0292b81d2ed2b3299a0630985f90","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    db_model \u003d models.SubPort"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    primary_keys \u003d [\u0027port_id\u0027, \u0027trunk_id\u0027]"},{"line_number":35,"context_line":"    foreign_keys \u003d {\u0027trunk_id\u0027: \u0027id\u0027}"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    fields \u003d {"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_f5b627f8","line":34,"updated":"2016-06-15 12:07:01.000000000","message":"this should be updated, trunk_id should be removed, see [1]\n\n[1] https://review.openstack.org/#/c/327201/3/neutron/services/trunk/models.py","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"80d0805f8a255e3aff43c16afad043daa405a93a","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    db_model \u003d models.SubPort"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    primary_keys \u003d [\u0027port_id\u0027, \u0027trunk_id\u0027]"},{"line_number":35,"context_line":"    foreign_keys \u003d {\u0027trunk_id\u0027: \u0027id\u0027}"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    fields \u003d {"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_832489c6","line":34,"in_reply_to":"7aa08908_230347c0","updated":"2016-06-16 12:08:30.000000000","message":"fixed","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"168ea126d27a746e9f6fb54cfb9f6da6e4607e59","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    db_model \u003d models.SubPort"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    primary_keys \u003d [\u0027port_id\u0027, \u0027trunk_id\u0027]"},{"line_number":35,"context_line":"    foreign_keys \u003d {\u0027trunk_id\u0027: \u0027id\u0027}"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    fields \u003d {"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_230347c0","line":34,"in_reply_to":"7aa08908_f5b627f8","updated":"2016-06-15 15:22:33.000000000","message":"ok, great!","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":6788,"name":"Rossella Sblendido","email":"rsblendido@suse.com","username":"rossella-o"},"change_message_id":"1e0e498633fe0292b81d2ed2b3299a0630985f90","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    db_model \u003d models.SubPort"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    primary_keys \u003d [\u0027port_id\u0027, \u0027trunk_id\u0027]"},{"line_number":35,"context_line":"    foreign_keys \u003d {\u0027trunk_id\u0027: \u0027id\u0027}"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    fields \u003d {"},{"line_number":38,"context_line":"        \u0027port_id\u0027: obj_fields.UUIDField(),"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_157ad377","line":35,"updated":"2016-06-15 12:07:01.000000000","message":"no need for this here, we use it only to load synthetic fields and this object has no synthetic fields.","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"168ea126d27a746e9f6fb54cfb9f6da6e4607e59","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    db_model \u003d models.SubPort"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    primary_keys \u003d [\u0027port_id\u0027, \u0027trunk_id\u0027]"},{"line_number":35,"context_line":"    foreign_keys \u003d {\u0027trunk_id\u0027: \u0027id\u0027}"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    fields \u003d {"},{"line_number":38,"context_line":"        \u0027port_id\u0027: obj_fields.UUIDField(),"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_2324e7b0","line":35,"in_reply_to":"7aa08908_157ad377","updated":"2016-06-15 15:22:33.000000000","message":"Please consider looking at [1] and [2]. It is used by Trunk.load_synthetic_fields.\n\n[1] https://github.com/openstack/neutron/blob/a68c425/neutron/objects/base.py#L406\n[2] https://review.openstack.org/#/c/327345","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":6788,"name":"Rossella Sblendido","email":"rsblendido@suse.com","username":"rossella-o"},"change_message_id":"1e0e498633fe0292b81d2ed2b3299a0630985f90","unresolved":false,"context_lines":[{"line_number":44,"context_line":"    fields_no_update \u003d [\u0027segmentation_type\u0027, \u0027segmentation_id\u0027]"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def create(self):"},{"line_number":47,"context_line":"        with db_api.autonested_transaction(self._context.session):"},{"line_number":48,"context_line":"            try:"},{"line_number":49,"context_line":"                super(SubPort, self).create()"},{"line_number":50,"context_line":"            except o_db_exc.DBReferenceError as ex:"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_c4289788","line":47,"updated":"2016-06-15 12:07:01.000000000","message":"this line should be moved inside the try block, otherwise the session is not properly rolled back, see [1]\n\n[1] http://docs.sqlalchemy.org/en/latest/faq/sessions.html#this-session-s-transaction-has-been-rolled-back-due-to-a-previous-exception-during-flush-or-similar","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"80d0805f8a255e3aff43c16afad043daa405a93a","unresolved":false,"context_lines":[{"line_number":44,"context_line":"    fields_no_update \u003d [\u0027segmentation_type\u0027, \u0027segmentation_id\u0027]"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def create(self):"},{"line_number":47,"context_line":"        with db_api.autonested_transaction(self._context.session):"},{"line_number":48,"context_line":"            try:"},{"line_number":49,"context_line":"                super(SubPort, self).create()"},{"line_number":50,"context_line":"            except o_db_exc.DBReferenceError as ex:"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_8d25da0b","line":47,"in_reply_to":"7aa08908_c4289788","updated":"2016-06-16 12:08:30.000000000","message":"I\u0027m not sure what do you mean here. \u0027super.create\u0027 has it\u0027s own autonested_transaction, so moving \u0027this line\u0027 inside the \u0027try\u0027 block would be technically a no-op. \u0027This line\u0027 is here for \u0027get_object\u0027 to be part of the same transaction that \u0027super.create\u0027 is so that it sees the same DB state. Since the \u0027except\u0027 block would always raise an exception, that will lead to rollback in \u0027this line\u0027 as well (and that matches the \"The usage of the Session should fit within a structure similar to this\" from the link you mentioned).","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":6788,"name":"Rossella Sblendido","email":"rsblendido@suse.com","username":"rossella-o"},"change_message_id":"1e0e498633fe0292b81d2ed2b3299a0630985f90","unresolved":false,"context_lines":[{"line_number":48,"context_line":"            try:"},{"line_number":49,"context_line":"                super(SubPort, self).create()"},{"line_number":50,"context_line":"            except o_db_exc.DBReferenceError as ex:"},{"line_number":51,"context_line":"                if ex.key_table is None:"},{"line_number":52,"context_line":"                    # workaround for sqlite as the exception does not contain"},{"line_number":53,"context_line":"                    # the required details"},{"line_number":54,"context_line":"                    if not Trunk.get_object(self._context, id\u003dself.trunk_id):"},{"line_number":55,"context_line":"                        ex.key_table \u003d Trunk.db_model.__tablename__"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"                if ex.key_table \u003d\u003d Trunk.db_model.__tablename__:"},{"line_number":58,"context_line":"                    raise t_exc.TrunkNotFound(trunk_id\u003dself.trunk_id)"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"                raise n_exc.PortNotFound(port_id\u003dself.port_id)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"@obj_base.VersionedObjectRegistry.register"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_84b96f18","line":60,"range":{"start_line":51,"start_character":0,"end_line":60,"end_character":62},"updated":"2016-06-15 12:07:01.000000000","message":"this could simply be:\n\nif ex.key_table is None:\n  if not Trunk.get_object(self._context, id\u003dself.trunk_id):\n      raise t_exc.TrunkNotFound(trunk_id\u003dself.trunk_id)\n\nraise n_exc.PortNotFound(port_id\u003dself.port_id)","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"168ea126d27a746e9f6fb54cfb9f6da6e4607e59","unresolved":false,"context_lines":[{"line_number":48,"context_line":"            try:"},{"line_number":49,"context_line":"                super(SubPort, self).create()"},{"line_number":50,"context_line":"            except o_db_exc.DBReferenceError as ex:"},{"line_number":51,"context_line":"                if ex.key_table is None:"},{"line_number":52,"context_line":"                    # workaround for sqlite as the exception does not contain"},{"line_number":53,"context_line":"                    # the required details"},{"line_number":54,"context_line":"                    if not Trunk.get_object(self._context, id\u003dself.trunk_id):"},{"line_number":55,"context_line":"                        ex.key_table \u003d Trunk.db_model.__tablename__"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"                if ex.key_table \u003d\u003d Trunk.db_model.__tablename__:"},{"line_number":58,"context_line":"                    raise t_exc.TrunkNotFound(trunk_id\u003dself.trunk_id)"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"                raise n_exc.PortNotFound(port_id\u003dself.port_id)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"@obj_base.VersionedObjectRegistry.register"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_03ec4b28","line":60,"range":{"start_line":51,"start_character":0,"end_line":60,"end_character":62},"in_reply_to":"7aa08908_84b96f18","updated":"2016-06-15 15:22:33.000000000","message":"Sorry, but it could not. The suggested code would always raise PortNotFound for non-sqlite engines.","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":6788,"name":"Rossella Sblendido","email":"rsblendido@suse.com","username":"rossella-o"},"change_message_id":"1e0e498633fe0292b81d2ed2b3299a0630985f90","unresolved":false,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    synthetic_fields \u003d [\u0027sub_ports\u0027]"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def __init__(self, context\u003dNone, **kwargs):"},{"line_number":82,"context_line":"        if (\u0027tenant_id\u0027 not in kwargs and"},{"line_number":83,"context_line":"                getattr(context, \u0027tenant_id\u0027, None) is not None):"},{"line_number":84,"context_line":"            kwargs[\u0027tenant_id\u0027] \u003d context.tenant_id"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_c407f7c7","line":81,"updated":"2016-06-15 12:07:01.000000000","message":"I don\u0027t think you need to override this.","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"80d0805f8a255e3aff43c16afad043daa405a93a","unresolved":false,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    synthetic_fields \u003d [\u0027sub_ports\u0027]"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def __init__(self, context\u003dNone, **kwargs):"},{"line_number":82,"context_line":"        if (\u0027tenant_id\u0027 not in kwargs and"},{"line_number":83,"context_line":"                getattr(context, \u0027tenant_id\u0027, None) is not None):"},{"line_number":84,"context_line":"            kwargs[\u0027tenant_id\u0027] \u003d context.tenant_id"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_c32e91a4","line":81,"in_reply_to":"7aa08908_1c030cc0","updated":"2016-06-16 12:08:30.000000000","message":"fixed","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"168ea126d27a746e9f6fb54cfb9f6da6e4607e59","unresolved":false,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    synthetic_fields \u003d [\u0027sub_ports\u0027]"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def __init__(self, context\u003dNone, **kwargs):"},{"line_number":82,"context_line":"        if (\u0027tenant_id\u0027 not in kwargs and"},{"line_number":83,"context_line":"                getattr(context, \u0027tenant_id\u0027, None) is not None):"},{"line_number":84,"context_line":"            kwargs[\u0027tenant_id\u0027] \u003d context.tenant_id"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_1c030cc0","line":81,"in_reply_to":"7aa08908_c407f7c7","updated":"2016-06-15 15:22:33.000000000","message":"The point of this was to allow sub-port information to be passed to Trunk as a list of dict-like objects. Because back then we could not pass sub_ports to the Trunk as SubPort objects (OVO would not allow us to create SubPort object without trunk_id so it was a snake eating its tail).\n\nBut with the recent update to SubPort model that removed trunk_id from primary key we can now use SubPort here, so it\u0027s not needed anymore. That should also make this more OVO-ish.\n\nThanks for pointing out the model update (I already tried dropping \u0027trunk_id\u0027 from primary key in [1], but did not succeed back then).\n\n[1] https://review.openstack.org/#/c/310410","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":6788,"name":"Rossella Sblendido","email":"rsblendido@suse.com","username":"rossella-o"},"change_message_id":"1e0e498633fe0292b81d2ed2b3299a0630985f90","unresolved":false,"context_lines":[{"line_number":81,"context_line":"    def __init__(self, context\u003dNone, **kwargs):"},{"line_number":82,"context_line":"        if (\u0027tenant_id\u0027 not in kwargs and"},{"line_number":83,"context_line":"                getattr(context, \u0027tenant_id\u0027, None) is not None):"},{"line_number":84,"context_line":"            kwargs[\u0027tenant_id\u0027] \u003d context.tenant_id"},{"line_number":85,"context_line":"        self._sub_ports_attrs \u003d kwargs.pop(\u0027sub_ports\u0027, [])"},{"line_number":86,"context_line":"        super(Trunk, self).__init__(context, **kwargs)"},{"line_number":87,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_e45b13f8","line":84,"updated":"2016-06-15 12:07:01.000000000","message":"tenant_id shouldn\u0027t be silently copied from the context, it should be passed to the constructor","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"80d0805f8a255e3aff43c16afad043daa405a93a","unresolved":false,"context_lines":[{"line_number":81,"context_line":"    def __init__(self, context\u003dNone, **kwargs):"},{"line_number":82,"context_line":"        if (\u0027tenant_id\u0027 not in kwargs and"},{"line_number":83,"context_line":"                getattr(context, \u0027tenant_id\u0027, None) is not None):"},{"line_number":84,"context_line":"            kwargs[\u0027tenant_id\u0027] \u003d context.tenant_id"},{"line_number":85,"context_line":"        self._sub_ports_attrs \u003d kwargs.pop(\u0027sub_ports\u0027, [])"},{"line_number":86,"context_line":"        super(Trunk, self).__init__(context, **kwargs)"},{"line_number":87,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_0317f954","line":84,"in_reply_to":"7aa08908_467141a8","updated":"2016-06-16 12:08:30.000000000","message":"fixed","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"168ea126d27a746e9f6fb54cfb9f6da6e4607e59","unresolved":false,"context_lines":[{"line_number":81,"context_line":"    def __init__(self, context\u003dNone, **kwargs):"},{"line_number":82,"context_line":"        if (\u0027tenant_id\u0027 not in kwargs and"},{"line_number":83,"context_line":"                getattr(context, \u0027tenant_id\u0027, None) is not None):"},{"line_number":84,"context_line":"            kwargs[\u0027tenant_id\u0027] \u003d context.tenant_id"},{"line_number":85,"context_line":"        self._sub_ports_attrs \u003d kwargs.pop(\u0027sub_ports\u0027, [])"},{"line_number":86,"context_line":"        super(Trunk, self).__init__(context, **kwargs)"},{"line_number":87,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_467141a8","line":84,"in_reply_to":"7aa08908_e45b13f8","updated":"2016-06-15 15:22:33.000000000","message":"ok","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"dd82652716af72a960f732425c1f4ff531751909","unresolved":false,"context_lines":[{"line_number":86,"context_line":"        super(Trunk, self).__init__(context, **kwargs)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def create(self):"},{"line_number":89,"context_line":"        with db_api.autonested_transaction(self._context.session):"},{"line_number":90,"context_line":"            try:"},{"line_number":91,"context_line":"                super(Trunk, self).create()"},{"line_number":92,"context_line":"            except o_db_exc.DBReferenceError:"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_1af15a02","line":89,"updated":"2016-06-15 12:06:30.000000000","message":"btw we should now use .obj_context instead of ._context.","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":6788,"name":"Rossella Sblendido","email":"rsblendido@suse.com","username":"rossella-o"},"change_message_id":"1e0e498633fe0292b81d2ed2b3299a0630985f90","unresolved":false,"context_lines":[{"line_number":86,"context_line":"        super(Trunk, self).__init__(context, **kwargs)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def create(self):"},{"line_number":89,"context_line":"        with db_api.autonested_transaction(self._context.session):"},{"line_number":90,"context_line":"            try:"},{"line_number":91,"context_line":"                super(Trunk, self).create()"},{"line_number":92,"context_line":"            except o_db_exc.DBReferenceError:"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_44f4a7ce","line":89,"updated":"2016-06-15 12:07:01.000000000","message":"ditto","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"168ea126d27a746e9f6fb54cfb9f6da6e4607e59","unresolved":false,"context_lines":[{"line_number":86,"context_line":"        super(Trunk, self).__init__(context, **kwargs)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def create(self):"},{"line_number":89,"context_line":"        with db_api.autonested_transaction(self._context.session):"},{"line_number":90,"context_line":"            try:"},{"line_number":91,"context_line":"                super(Trunk, self).create()"},{"line_number":92,"context_line":"            except o_db_exc.DBReferenceError:"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_667a7d79","line":89,"in_reply_to":"7aa08908_44f4a7ce","updated":"2016-06-15 15:22:33.000000000","message":"ok","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"80d0805f8a255e3aff43c16afad043daa405a93a","unresolved":false,"context_lines":[{"line_number":86,"context_line":"        super(Trunk, self).__init__(context, **kwargs)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def create(self):"},{"line_number":89,"context_line":"        with db_api.autonested_transaction(self._context.session):"},{"line_number":90,"context_line":"            try:"},{"line_number":91,"context_line":"                super(Trunk, self).create()"},{"line_number":92,"context_line":"            except o_db_exc.DBReferenceError:"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_4311015d","line":89,"in_reply_to":"7aa08908_667a7d79","updated":"2016-06-16 12:08:30.000000000","message":"@Ihar, fixed","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":6788,"name":"Rossella Sblendido","email":"rsblendido@suse.com","username":"rossella-o"},"change_message_id":"1e0e498633fe0292b81d2ed2b3299a0630985f90","unresolved":false,"context_lines":[{"line_number":92,"context_line":"            except o_db_exc.DBReferenceError:"},{"line_number":93,"context_line":"                raise n_exc.PortNotFound(port_id\u003dself.port_id)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"            sub_ports \u003d [SubPort(self._context, trunk_id\u003dself.id, **attrs)"},{"line_number":96,"context_line":"                         for attrs in self._sub_ports_attrs]"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"            for sub_port in sub_ports:"},{"line_number":99,"context_line":"                sub_port.create()"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_3abff6fd","line":96,"range":{"start_line":95,"start_character":0,"end_line":96,"end_character":60},"updated":"2016-06-15 12:07:01.000000000","message":"I don\u0027t think you need this, self.sub_ports contains SubPort objects already","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"168ea126d27a746e9f6fb54cfb9f6da6e4607e59","unresolved":false,"context_lines":[{"line_number":92,"context_line":"            except o_db_exc.DBReferenceError:"},{"line_number":93,"context_line":"                raise n_exc.PortNotFound(port_id\u003dself.port_id)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"            sub_ports \u003d [SubPort(self._context, trunk_id\u003dself.id, **attrs)"},{"line_number":96,"context_line":"                         for attrs in self._sub_ports_attrs]"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"            for sub_port in sub_ports:"},{"line_number":99,"context_line":"                sub_port.create()"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_9cc89c58","line":96,"range":{"start_line":95,"start_character":0,"end_line":96,"end_character":60},"in_reply_to":"7aa08908_3abff6fd","updated":"2016-06-15 15:22:33.000000000","message":"It does not (necessary) contain SubPorts in this PS, but just a list of dict-like objects. But I\u0027ll remove it in the next PS (see L81 comment).","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"80d0805f8a255e3aff43c16afad043daa405a93a","unresolved":false,"context_lines":[{"line_number":92,"context_line":"            except o_db_exc.DBReferenceError:"},{"line_number":93,"context_line":"                raise n_exc.PortNotFound(port_id\u003dself.port_id)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"            sub_ports \u003d [SubPort(self._context, trunk_id\u003dself.id, **attrs)"},{"line_number":96,"context_line":"                         for attrs in self._sub_ports_attrs]"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"            for sub_port in sub_ports:"},{"line_number":99,"context_line":"                sub_port.create()"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_a300a503","line":96,"range":{"start_line":95,"start_character":0,"end_line":96,"end_character":60},"in_reply_to":"7aa08908_9cc89c58","updated":"2016-06-16 12:08:30.000000000","message":"fixed","commit_id":"afee11222265853330addd90f8253c9f4e2c6851"},{"author":{"_account_id":6788,"name":"Rossella Sblendido","email":"rsblendido@suse.com","username":"rossella-o"},"change_message_id":"fc10cbe5d9448342411da2702be93e33653dac39","unresolved":false,"context_lines":[{"line_number":51,"context_line":"                if ex.key_table is None:"},{"line_number":52,"context_line":"                    # workaround for sqlite as the exception does not contain"},{"line_number":53,"context_line":"                    # the required details"},{"line_number":54,"context_line":"                    if not Trunk.get_object(self.obj_context,"},{"line_number":55,"context_line":"                                            id\u003dself.trunk_id):"},{"line_number":56,"context_line":"                        ex.key_table \u003d Trunk.db_model.__tablename__"},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_e94e3a95","line":54,"updated":"2016-06-20 13:14:27.000000000","message":"Expanding from my comment from the previous PS...in 50 you catch a DB exception and here you access the DB again. Since the session was not rolled back, this leads to problem, please read [1], quoting here \"many database operations require a ROLLBACK in any case. Postgres in particular has operations which, once failed, the transaction is not allowed to continue\". The \"with db_api\" should be moved inside the try block\n\n[1] http://docs.sqlalchemy.org/en/latest/faq/sessions.html#this-session-s-transaction-has-been-rolled-back-due-to-a-previous-exception-during-flush-or-similar","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"07d6f7d66048b179b809a5304d2a9f100d6f357b","unresolved":false,"context_lines":[{"line_number":51,"context_line":"                if ex.key_table is None:"},{"line_number":52,"context_line":"                    # workaround for sqlite as the exception does not contain"},{"line_number":53,"context_line":"                    # the required details"},{"line_number":54,"context_line":"                    if not Trunk.get_object(self.obj_context,"},{"line_number":55,"context_line":"                                            id\u003dself.trunk_id):"},{"line_number":56,"context_line":"                        ex.key_table \u003d Trunk.db_model.__tablename__"},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3aaa91ec_67260918","line":54,"in_reply_to":"3aaa91ec_216fd493","updated":"2016-06-21 19:36:54.000000000","message":"There was a bit of discussion on the matter in private irc. Basically, as long as we are a bit more explicit here about why we can assume that it\u0027s only sqlite that can trigger it, maybe with a more broad comment, that should be fine.","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"7df632d3208d1d5c129c9f470b1ff239e826340b","unresolved":false,"context_lines":[{"line_number":51,"context_line":"                if ex.key_table is None:"},{"line_number":52,"context_line":"                    # workaround for sqlite as the exception does not contain"},{"line_number":53,"context_line":"                    # the required details"},{"line_number":54,"context_line":"                    if not Trunk.get_object(self.obj_context,"},{"line_number":55,"context_line":"                                            id\u003dself.trunk_id):"},{"line_number":56,"context_line":"                        ex.key_table \u003d Trunk.db_model.__tablename__"},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3aaa91ec_a8f9d6ca","line":54,"in_reply_to":"3aaa91ec_67260918","updated":"2016-06-22 00:44:52.000000000","message":"Actually I believe that the ROLLBACK problem [1] that Rossella mentioned does not apply here. It obviously does not for sqlite as the unit tests do not raise unexpected exceptions (I\u0027m also sure MySQL and Oracle behave the same way), but I was not sure about PostgreSQL.\n\nSo I\u0027ve checked it [2] and it seems that PostgreSQL does behave as expected and it is possible to query the database after issuing a ROLLBACK TO SAVEPOINT (and that is what SQLAlchemy would do [3] when a DBReferenceError is thrown inside super.create as it has it\u0027s own sub-transaction [4] that would be rolled back).\n\n\u003e Basically, as long as we are a bit more explicit here about why we can assume that it\u0027s only sqlite that can trigger it, maybe with a more broad comment, that should be fine.\n\n@Ihar, in fact we do not need to assume that only \u0027sqlite\u0027 triggers it. Considering that [1] is not a problem here, that code block should be relevant for any db backend that does not have proper DBReferenceError exception support in oslo.db.\n\n[1] http://docs.sqlalchemy.org/en/latest/faq/sessions.html#this-session-s-transaction-has-been-rolled-back-due-to-a-previous-exception-during-flush-or-similar\n[2] http://paste.openstack.org/show/521013/\n[3] https://github.com/zzzeek/sqlalchemy/blob/528509e/lib/sqlalchemy/orm/session.py#L495-L506\n[4] https://github.com/openstack/neutron/blob/a68c425/neutron/objects/base.py#L415","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"6c2c430b5576067aa57512917e4f1523cca50468","unresolved":false,"context_lines":[{"line_number":51,"context_line":"                if ex.key_table is None:"},{"line_number":52,"context_line":"                    # workaround for sqlite as the exception does not contain"},{"line_number":53,"context_line":"                    # the required details"},{"line_number":54,"context_line":"                    if not Trunk.get_object(self.obj_context,"},{"line_number":55,"context_line":"                                            id\u003dself.trunk_id):"},{"line_number":56,"context_line":"                        ex.key_table \u003d Trunk.db_model.__tablename__"},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3aaa91ec_216fd493","line":54,"in_reply_to":"5a9d85d2_78f2d170","updated":"2016-06-21 18:21:36.000000000","message":"Personally, I like it this way.  The guard is against backends that don\u0027t have ex.key_table.  To me, it doesn\u0027t really matter that we think it is only sqlite.  If we are explicit about the backend and we happen to miss one that has the same problem, then I think we\u0027ve done a bad thing because we\u0027ll have a bug for that backend that wouldn\u0027t have appeared if we hadn\u0027t been explicit about the backend.\n\nHere, we know that if the exception doesn\u0027t have .key_table then we have more work to do and that is what the code says.  I like it that way.","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"6eb65204a1d138c52246b1c6ed35a836837b2e49","unresolved":false,"context_lines":[{"line_number":51,"context_line":"                if ex.key_table is None:"},{"line_number":52,"context_line":"                    # workaround for sqlite as the exception does not contain"},{"line_number":53,"context_line":"                    # the required details"},{"line_number":54,"context_line":"                    if not Trunk.get_object(self.obj_context,"},{"line_number":55,"context_line":"                                            id\u003dself.trunk_id):"},{"line_number":56,"context_line":"                        ex.key_table \u003d Trunk.db_model.__tablename__"},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_78f2d170","line":54,"in_reply_to":"5a9d85d2_a020c09c","updated":"2016-06-21 15:19:55.000000000","message":"Can we be more explicit about the backend here? Is there a way to check that it\u0027s indeed sqlite? I prefer we guard the code section against other backends, including DB2 or any other database in the wild.","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"7717ddbbc4cd221953ffceabe7ea67d3f0c4cf6c","unresolved":false,"context_lines":[{"line_number":51,"context_line":"                if ex.key_table is None:"},{"line_number":52,"context_line":"                    # workaround for sqlite as the exception does not contain"},{"line_number":53,"context_line":"                    # the required details"},{"line_number":54,"context_line":"                    if not Trunk.get_object(self.obj_context,"},{"line_number":55,"context_line":"                                            id\u003dself.trunk_id):"},{"line_number":56,"context_line":"                        ex.key_table \u003d Trunk.db_model.__tablename__"},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_a020c09c","line":54,"in_reply_to":"5a9d85d2_e94e3a95","updated":"2016-06-20 14:58:30.000000000","message":"Rossella, this code block is a workaround for \u0027sqlite\u0027 not providing the details in DBReferenceError. It does work for \u0027sqlite\u0027, otherwise that would lead to an exception in unit tests. And it is not supposed to be triggered for MySQL/Postgres as they both provide \u0027key_table\u0027 in DBReferenceError.\n\nAlso note that super.create() would issue a ROLLBACK [1] by itself as it has it\u0027s own transactional context.\n\n[1] https://github.com/zzzeek/sqlalchemy/blob/528509e/lib/sqlalchemy/orm/session.py#L495-L506","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":6788,"name":"Rossella Sblendido","email":"rsblendido@suse.com","username":"rossella-o"},"change_message_id":"fc10cbe5d9448342411da2702be93e33653dac39","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                    # the required details"},{"line_number":54,"context_line":"                    if not Trunk.get_object(self.obj_context,"},{"line_number":55,"context_line":"                                            id\u003dself.trunk_id):"},{"line_number":56,"context_line":"                        ex.key_table \u003d Trunk.db_model.__tablename__"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"                if ex.key_table \u003d\u003d Trunk.db_model.__tablename__:"},{"line_number":59,"context_line":"                    raise t_exc.TrunkNotFound(trunk_id\u003dself.trunk_id)"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_1163f0dd","line":56,"range":{"start_line":56,"start_character":24,"end_line":56,"end_character":67},"updated":"2016-06-20 13:14:27.000000000","message":"here you can raise TrunkNotFound directly instead of setting the tablename and raise at line 59, that\u0027s confusing.","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"6eb65204a1d138c52246b1c6ed35a836837b2e49","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                    # the required details"},{"line_number":54,"context_line":"                    if not Trunk.get_object(self.obj_context,"},{"line_number":55,"context_line":"                                            id\u003dself.trunk_id):"},{"line_number":56,"context_line":"                        ex.key_table \u003d Trunk.db_model.__tablename__"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"                if ex.key_table \u003d\u003d Trunk.db_model.__tablename__:"},{"line_number":59,"context_line":"                    raise t_exc.TrunkNotFound(trunk_id\u003dself.trunk_id)"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_381de9bd","line":56,"range":{"start_line":56,"start_character":24,"end_line":56,"end_character":67},"in_reply_to":"5a9d85d2_00bc3404","updated":"2016-06-21 15:19:55.000000000","message":"That\u0027s a fair explanation.","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"7717ddbbc4cd221953ffceabe7ea67d3f0c4cf6c","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                    # the required details"},{"line_number":54,"context_line":"                    if not Trunk.get_object(self.obj_context,"},{"line_number":55,"context_line":"                                            id\u003dself.trunk_id):"},{"line_number":56,"context_line":"                        ex.key_table \u003d Trunk.db_model.__tablename__"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"                if ex.key_table \u003d\u003d Trunk.db_model.__tablename__:"},{"line_number":59,"context_line":"                    raise t_exc.TrunkNotFound(trunk_id\u003dself.trunk_id)"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_00bc3404","line":56,"range":{"start_line":56,"start_character":24,"end_line":56,"end_character":67},"in_reply_to":"5a9d85d2_1163f0dd","updated":"2016-06-20 14:58:30.000000000","message":"No. This code block is a workaround for \u0027sqlite\u0027 and is only supposed to only fix that missing DBReferenceError.key_table.\n\nI don\u0027t want the same exception (for the same exceptional case) to be thrown from different places depending on the DB backend.","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"85ce562ec9ad39fcd7136e37efba5c956695fc25","unresolved":false,"context_lines":[{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    synthetic_fields \u003d [\u0027sub_ports\u0027]"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def create(self):"},{"line_number":83,"context_line":"        with db_api.autonested_transaction(self.obj_context.session):"},{"line_number":84,"context_line":"            sub_ports \u003d []"},{"line_number":85,"context_line":"            if self.obj_attr_is_set(\u0027sub_ports\u0027):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_27e9931b","line":82,"updated":"2016-06-20 10:56:25.000000000","message":"Don\u0027t you also need update() to be able to modify the list after it\u0027s initially created?","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"07d6f7d66048b179b809a5304d2a9f100d6f357b","unresolved":false,"context_lines":[{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    synthetic_fields \u003d [\u0027sub_ports\u0027]"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def create(self):"},{"line_number":83,"context_line":"        with db_api.autonested_transaction(self.obj_context.session):"},{"line_number":84,"context_line":"            sub_ports \u003d []"},{"line_number":85,"context_line":"            if self.obj_attr_is_set(\u0027sub_ports\u0027):"}],"source_content_type":"text/x-python","patch_set":5,"id":"3aaa91ec_c77d3de9","line":82,"in_reply_to":"3aaa91ec_21c7d446","updated":"2016-06-21 19:36:54.000000000","message":"I think it\u0027s ok to leave it as-is, just having a TODO for the limitation.","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"000ce7cb77931dabe179d9a248b67462a416ecfd","unresolved":false,"context_lines":[{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    synthetic_fields \u003d [\u0027sub_ports\u0027]"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def create(self):"},{"line_number":83,"context_line":"        with db_api.autonested_transaction(self.obj_context.session):"},{"line_number":84,"context_line":"            sub_ports \u003d []"},{"line_number":85,"context_line":"            if self.obj_attr_is_set(\u0027sub_ports\u0027):"}],"source_content_type":"text/x-python","patch_set":5,"id":"3aaa91ec_adaa8b17","line":82,"in_reply_to":"3aaa91ec_c77d3de9","updated":"2016-06-21 22:53:57.000000000","message":"+1, we don\u0027t support PUT on the API. There doesn\u0027t seem to be much argument about not supporting it, so I\u0027d like to see us move on and set the update discussion aside for now.","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"6eb65204a1d138c52246b1c6ed35a836837b2e49","unresolved":false,"context_lines":[{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    synthetic_fields \u003d [\u0027sub_ports\u0027]"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def create(self):"},{"line_number":83,"context_line":"        with db_api.autonested_transaction(self.obj_context.session):"},{"line_number":84,"context_line":"            sub_ports \u003d []"},{"line_number":85,"context_line":"            if self.obj_attr_is_set(\u0027sub_ports\u0027):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_58f395d6","line":82,"in_reply_to":"5a9d85d2_0b1bb573","updated":"2016-06-21 15:19:55.000000000","message":"Yeah, but then your API for the object is not complete. I prefer if we keep it symmetric for both create and update. Do you think it\u0027s too much to take?","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"7717ddbbc4cd221953ffceabe7ea67d3f0c4cf6c","unresolved":false,"context_lines":[{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    synthetic_fields \u003d [\u0027sub_ports\u0027]"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def create(self):"},{"line_number":83,"context_line":"        with db_api.autonested_transaction(self.obj_context.session):"},{"line_number":84,"context_line":"            sub_ports \u003d []"},{"line_number":85,"context_line":"            if self.obj_attr_is_set(\u0027sub_ports\u0027):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_0b1bb573","line":82,"in_reply_to":"5a9d85d2_27e9931b","updated":"2016-06-20 14:58:30.000000000","message":"Not really. SubPorts are supposed to be added/deleted by using SubPort.create/delete. Using Trunk.sub_ports (append/remove) + update would be much less efficient (i.e. that would at least require an unnecessary fetch of all Trunk\u0027s children SubPorts).\n\nInitially that functionality was implemented as a helper method in the original PS [1], but it was suggested [2] to make it part of \u0027create\u0027.\n\nShould I revert this to be a helper method (that would also solve the exception translation issue at L91)?\n\n[1] https://review.openstack.org/#/c/310410\n[2] https://review.openstack.org/#/c/310410/7/neutron/objects/trunk.py@91","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"6c2c430b5576067aa57512917e4f1523cca50468","unresolved":false,"context_lines":[{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    synthetic_fields \u003d [\u0027sub_ports\u0027]"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def create(self):"},{"line_number":83,"context_line":"        with db_api.autonested_transaction(self.obj_context.session):"},{"line_number":84,"context_line":"            sub_ports \u003d []"},{"line_number":85,"context_line":"            if self.obj_attr_is_set(\u0027sub_ports\u0027):"}],"source_content_type":"text/x-python","patch_set":5,"id":"3aaa91ec_21c7d446","line":82,"in_reply_to":"5a9d85d2_58f395d6","updated":"2016-06-21 18:21:36.000000000","message":"Could we break this discussion off in to a follow-on patch?  The proposed API [1] doesn\u0027t allow PUT for the list of sub-ports.  I\u0027d rather merge this like it is and then discuss expanding the API to allow PUT later.  That would allow us to unblock the API [1] patch which depends on this.\n\n [1] https://review.openstack.org/#/c/320092/19/neutron/extensions/trunk.py","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"85ce562ec9ad39fcd7136e37efba5c956695fc25","unresolved":false,"context_lines":[{"line_number":88,"context_line":"            try:"},{"line_number":89,"context_line":"                super(Trunk, self).create()"},{"line_number":90,"context_line":"            except o_db_exc.DBReferenceError:"},{"line_number":91,"context_line":"                raise n_exc.PortNotFound(port_id\u003dself.port_id)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"            for sub_port in sub_ports:"},{"line_number":94,"context_line":"                sub_port.trunk_id \u003d self.id"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_e755cbc6","line":91,"updated":"2016-06-20 10:56:25.000000000","message":"I am a bit uneasy about doing the translation in objects layer just for that object. Doesn\u0027t it belong to either base class, or business logic that uses the object?","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"6eb65204a1d138c52246b1c6ed35a836837b2e49","unresolved":false,"context_lines":[{"line_number":88,"context_line":"            try:"},{"line_number":89,"context_line":"                super(Trunk, self).create()"},{"line_number":90,"context_line":"            except o_db_exc.DBReferenceError:"},{"line_number":91,"context_line":"                raise n_exc.PortNotFound(port_id\u003dself.port_id)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"            for sub_port in sub_ports:"},{"line_number":94,"context_line":"                sub_port.trunk_id \u003d self.id"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_b8ba796c","line":91,"in_reply_to":"5a9d85d2_0b3295f1","updated":"2016-06-21 15:19:55.000000000","message":"I guess it\u0027s ok to allow trunk object to behave in that way, and later we will consider if base class may help with this use case.","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"7717ddbbc4cd221953ffceabe7ea67d3f0c4cf6c","unresolved":false,"context_lines":[{"line_number":88,"context_line":"            try:"},{"line_number":89,"context_line":"                super(Trunk, self).create()"},{"line_number":90,"context_line":"            except o_db_exc.DBReferenceError:"},{"line_number":91,"context_line":"                raise n_exc.PortNotFound(port_id\u003dself.port_id)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"            for sub_port in sub_ports:"},{"line_number":94,"context_line":"                sub_port.trunk_id \u003d self.id"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_0b3295f1","line":91,"in_reply_to":"5a9d85d2_e755cbc6","updated":"2016-06-20 14:58:30.000000000","message":"comment @L82","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"4b641959d0aab67f5c221999570b3817b44069a9","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    db_model \u003d models.SubPort"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    primary_keys \u003d [\u0027port_id\u0027]"},{"line_number":35,"context_line":"    foreign_keys \u003d {\u0027trunk_id\u0027: \u0027id\u0027}"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    fields \u003d {"},{"line_number":38,"context_line":"        \u0027port_id\u0027: obj_fields.UUIDField(),"}],"source_content_type":"text/x-python","patch_set":6,"id":"3aaa91ec_53057ac0","line":35,"updated":"2016-06-22 04:59:17.000000000","message":"port_id has a foreign key constraint on it as well, don\u0027t we need \u0027port_id\u0027: \u0027id\u0027 here as well?","commit_id":"ce31e12166ddc72bc43c1beeec0ee07b9e10e6d6"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"f46e2f25174bb82805638c5f231b35cefb1ee9e9","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    db_model \u003d models.SubPort"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    primary_keys \u003d [\u0027port_id\u0027]"},{"line_number":35,"context_line":"    foreign_keys \u003d {\u0027trunk_id\u0027: \u0027id\u0027}"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    fields \u003d {"},{"line_number":38,"context_line":"        \u0027port_id\u0027: obj_fields.UUIDField(),"}],"source_content_type":"text/x-python","patch_set":6,"id":"3aaa91ec_f32c66ad","line":35,"in_reply_to":"3aaa91ec_53057ac0","updated":"2016-06-22 05:19:41.000000000","message":"Those keys are used to pull in relevant sub_ports in line 82.","commit_id":"ce31e12166ddc72bc43c1beeec0ee07b9e10e6d6"},{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"8814b400df3a785d55cd88ffd694d88a1d6db1d1","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    db_model \u003d models.SubPort"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    primary_keys \u003d [\u0027port_id\u0027]"},{"line_number":35,"context_line":"    foreign_keys \u003d {\u0027trunk_id\u0027: \u0027id\u0027}"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    fields \u003d {"},{"line_number":38,"context_line":"        \u0027port_id\u0027: obj_fields.UUIDField(),"}],"source_content_type":"text/x-python","patch_set":6,"id":"3aaa91ec_9620709d","line":35,"in_reply_to":"3aaa91ec_f32c66ad","updated":"2016-06-22 05:22:25.000000000","message":"Good to know, thanks for the explanation Ihar.","commit_id":"ce31e12166ddc72bc43c1beeec0ee07b9e10e6d6"}],"neutron/services/trunk/exceptions.py":[{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"39509c721f5e29f3a4cddf8e59b31cd333a8d787","unresolved":false,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"class TrunkNotFound(n_exc.NotFound):"},{"line_number":26,"context_line":"    message \u003d _(\"Trunk %(trunk_id)s could not be found.\")"}],"source_content_type":"text/x-python","patch_set":3,"id":"7aa08908_f81b41c8","line":26,"updated":"2016-06-07 16:26:16.000000000","message":"super-tiny-nit: maybe we use id instead of trunk_id since we\u0027re passing the actual id of the resource","commit_id":"8f6afaf06f3f1a409f047c6263c30cf0cdaeb5eb"},{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"ce2c5c2a5aa4a3d51903e0061e57deb8a31da6d3","unresolved":false,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"class TrunkNotFound(n_exc.NotFound):"},{"line_number":26,"context_line":"    message \u003d _(\"Trunk %(trunk_id)s could not be found.\")"}],"source_content_type":"text/x-python","patch_set":3,"id":"7aa08908_3ec12e55","line":26,"in_reply_to":"7aa08908_8812a807","updated":"2016-06-07 17:26:20.000000000","message":"Oh, neutron is using this convention now :) Alrighty then, don\u0027t swim upstream.","commit_id":"8f6afaf06f3f1a409f047c6263c30cf0cdaeb5eb"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"9eb5296cab5cd42fc7c1494d6f4450db48b6dcd4","unresolved":false,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"class TrunkNotFound(n_exc.NotFound):"},{"line_number":26,"context_line":"    message \u003d _(\"Trunk %(trunk_id)s could not be found.\")"}],"source_content_type":"text/x-python","patch_set":3,"id":"7aa08908_8812a807","line":26,"in_reply_to":"7aa08908_f81b41c8","updated":"2016-06-07 17:02:13.000000000","message":"Actually it\u0027s copied from neutron-lib exceptions [1], so I think it should be \u0027trunk_id\u0027 for consistency.\n\n[1] https://github.com/openstack/neutron-lib/blob/0867d7fe1bd12f1c23fea6456daeafe6ad1cb38e/neutron_lib/exceptions.py#L85-L94","commit_id":"8f6afaf06f3f1a409f047c6263c30cf0cdaeb5eb"}],"neutron/tests/unit/objects/test_base.py":[{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"6eb65204a1d138c52246b1c6ed35a836837b2e49","unresolved":false,"context_lines":[{"line_number":734,"context_line":""},{"line_number":735,"context_line":"        return obj_db_api.create_object(self.context, models_v2.Port, attrs)"},{"line_number":736,"context_line":""},{"line_number":737,"context_line":"    def _create_test_port(self, network):"},{"line_number":738,"context_line":"        # TODO(ihrachys): replace with port.create() once we get an object"},{"line_number":739,"context_line":"        # implementation for ports"},{"line_number":740,"context_line":"        self._port \u003d self._create_port(network_id\u003dnetwork[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_38032911","line":737,"updated":"2016-06-21 15:19:55.000000000","message":"Now that it\u0027s a shallow proxy method, do we even need it? Can we just remove it and make use of the new one in other places?","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"07d6f7d66048b179b809a5304d2a9f100d6f357b","unresolved":false,"context_lines":[{"line_number":734,"context_line":""},{"line_number":735,"context_line":"        return obj_db_api.create_object(self.context, models_v2.Port, attrs)"},{"line_number":736,"context_line":""},{"line_number":737,"context_line":"    def _create_test_port(self, network):"},{"line_number":738,"context_line":"        # TODO(ihrachys): replace with port.create() once we get an object"},{"line_number":739,"context_line":"        # implementation for ports"},{"line_number":740,"context_line":"        self._port \u003d self._create_port(network_id\u003dnetwork[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":5,"id":"3aaa91ec_a7775101","line":737,"in_reply_to":"3aaa91ec_c19410ea","updated":"2016-06-21 19:36:54.000000000","message":"Yes, we decided it may go in a separate patch. Also, it\u0027s not exactly a replacement since the original method also sets self._port","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"6c2c430b5576067aa57512917e4f1523cca50468","unresolved":false,"context_lines":[{"line_number":734,"context_line":""},{"line_number":735,"context_line":"        return obj_db_api.create_object(self.context, models_v2.Port, attrs)"},{"line_number":736,"context_line":""},{"line_number":737,"context_line":"    def _create_test_port(self, network):"},{"line_number":738,"context_line":"        # TODO(ihrachys): replace with port.create() once we get an object"},{"line_number":739,"context_line":"        # implementation for ports"},{"line_number":740,"context_line":"        self._port \u003d self._create_port(network_id\u003dnetwork[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":5,"id":"3aaa91ec_c19410ea","line":737,"in_reply_to":"5a9d85d2_38032911","updated":"2016-06-21 18:21:36.000000000","message":"Isn\u0027t this a bit off-topic?","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"6eb65204a1d138c52246b1c6ed35a836837b2e49","unresolved":false,"context_lines":[{"line_number":735,"context_line":"        return obj_db_api.create_object(self.context, models_v2.Port, attrs)"},{"line_number":736,"context_line":""},{"line_number":737,"context_line":"    def _create_test_port(self, network):"},{"line_number":738,"context_line":"        # TODO(ihrachys): replace with port.create() once we get an object"},{"line_number":739,"context_line":"        # implementation for ports"},{"line_number":740,"context_line":"        self._port \u003d self._create_port(network_id\u003dnetwork[\u0027id\u0027])"},{"line_number":741,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_7835b1f5","line":738,"updated":"2016-06-21 15:19:55.000000000","message":"This comment belongs to line 734.","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"07d6f7d66048b179b809a5304d2a9f100d6f357b","unresolved":false,"context_lines":[{"line_number":735,"context_line":"        return obj_db_api.create_object(self.context, models_v2.Port, attrs)"},{"line_number":736,"context_line":""},{"line_number":737,"context_line":"    def _create_test_port(self, network):"},{"line_number":738,"context_line":"        # TODO(ihrachys): replace with port.create() once we get an object"},{"line_number":739,"context_line":"        # implementation for ports"},{"line_number":740,"context_line":"        self._port \u003d self._create_port(network_id\u003dnetwork[\u0027id\u0027])"},{"line_number":741,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3aaa91ec_075f4573","line":738,"in_reply_to":"3aaa91ec_41b0208c","updated":"2016-06-21 19:36:54.000000000","message":"That\u0027s actually relevant, though minor.","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"6c2c430b5576067aa57512917e4f1523cca50468","unresolved":false,"context_lines":[{"line_number":735,"context_line":"        return obj_db_api.create_object(self.context, models_v2.Port, attrs)"},{"line_number":736,"context_line":""},{"line_number":737,"context_line":"    def _create_test_port(self, network):"},{"line_number":738,"context_line":"        # TODO(ihrachys): replace with port.create() once we get an object"},{"line_number":739,"context_line":"        # implementation for ports"},{"line_number":740,"context_line":"        self._port \u003d self._create_port(network_id\u003dnetwork[\u0027id\u0027])"},{"line_number":741,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3aaa91ec_41b0208c","line":738,"in_reply_to":"5a9d85d2_7835b1f5","updated":"2016-06-21 18:21:36.000000000","message":"ditto?","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"}],"neutron/tests/unit/objects/test_trunk.py":[{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"6eb65204a1d138c52246b1c6ed35a836837b2e49","unresolved":false,"context_lines":[{"line_number":28,"context_line":""},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"class SubPortDbObjectTestCase(test_base.BaseDbObjectTestCase,"},{"line_number":31,"context_line":"                              testlib_api.SqlTestCase):"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    _test_class \u003d t_obj.SubPort"},{"line_number":34,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_236adab3","line":31,"updated":"2016-06-21 15:19:55.000000000","message":"Ouch!","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"6eb65204a1d138c52246b1c6ed35a836837b2e49","unresolved":false,"context_lines":[{"line_number":67,"context_line":""},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"class TrunkDbObjectTestCase(test_base.BaseDbObjectTestCase,"},{"line_number":70,"context_line":"                            testlib_api.SqlTestCase):"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    _test_class \u003d t_obj.Trunk"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"5a9d85d2_4331e6eb","line":70,"updated":"2016-06-21 15:19:55.000000000","message":"\"Great!\"","commit_id":"1579a126d488002d0aab36454dfe5037ebeecd07"}]}
